Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram showing Apex code retrieving a user's IP address and corresponding location data on a map.
Apex

Get Apex user IP address and location - SFDC Developers

Ever needed to know where your users are logging in from? Apex can hand you their IP address and map it to city and country data without an external service, as long as you plan for the nulls.

The short answer

Auth.SessionManagement.getCurrentSession() returns the session map, and the SourceIp key holds the current user IP address. Take the LoginHistoryId from that same map, query LoginHistory for its LoginGeoId, then query LoginGeo for geographic details like city, state, and country. No external service is involved.

Key takeaways Auth.SessionManagement.getCurrentSession() returns the active session attributes, including the user IP address. LoginHistory holds a LoginGeoId lookup, so query LoginGeo through it for city, subdivision, country, and postal code. Guard the session call with Test.isRunningTest(), because unit tests run without an active session and the code breaks without it. Null check every step. VPN users and unmapped IP ranges have no LoginGeo record behind them. Query the session and location data once, outside any loop, so you do not run into SOQL limits.

Why you might need an Apex user IP address

If you've ever debugged a strange security issue, or had to show a banner only to users in one region, you know how handy the Apex user IP address is. I've worked on projects where we had to log exactly where a request came from to satisfy some strict audit requirements. It seems simple until you go looking for the right class to call.

Salesforce also stores a decent amount of geographic data behind the scenes. Combine the IP with login history and you get the city, state, and even the postal code, no external service required. That is enough to make a Salesforce universal logging framework tell you something useful about your users.

A realistic Salesforce Lightning interface showing a log entry with user IP address and geographic location details.

A realistic Salesforce Lightning interface showing a log entry with user IP address and geographic location details.

How to fetch the Apex user IP address and location

The class you want is Auth.SessionManagement, which holds the session details. Grabbing the IP is the easy half. For the location you have to hop from the session to the login history, and from there to the geo-location table.

The data isn't always there, either. If the user is on a VPN, or Salesforce hasn't mapped that IP range yet, the geo-location fields come back empty. Plan for nulls. I've seen teams fill their logs with NullPointerExceptions because they assumed every IP has a city attached to it.

Step 1: Grabbing the session IP

Pull the IP out of the current session map with the SourceIp key. I wrap that in a Test.isRunningTest() check, because unit tests have no active session and the code breaks the moment one runs without a guard.

Step 2: Finding the Geo-Location data

Once you have the LoginHistoryId from the session, query the LoginHistory object. It holds a lookup to LoginGeo, and that is where the location data lives: the subdivision (usually the state or province), the city, and the country. It's surprisingly accurate for most office-based users.

The Apex implementation

public void captureUserSessionData(List records) { // Grab the Apex user IP address and login history ID Map<String, String> sessionAttributes = Auth.SessionManagement.getCurrentSession();

String ipAddress = !Test.isRunningTest() ? sessionAttributes.get('SourceIp') : '1.1.1.1';
String loginId = !Test.isRunningTest() ? sessionAttributes.get('LoginHistoryId') : null;

if (String.isBlank(loginId)) return;

// We need to jump from History to Geo
List<LoginHistory> history = \[SELECT LoginGeoId FROM LoginHistory WHERE Id = :loginId LIMIT 1\];

if (history.isEmpty() || history\[0\].LoginGeoId == null) return;

LoginGeo geo = \[SELECT City, Subdivision, Country, PostalCode 
                FROM LoginGeo 
                WHERE Id = :history\[0\].LoginGeoId 
                LIMIT 1\];

// Now we stamp the data onto our records
for (Account acc : records) {
    acc.User\_IP\_Address\_\_c = ipAddress;
    acc.User\_Location\_\_c = geo.City + ', ' + geo.Subdivision + ' ' + geo.Country;
}

}

Don't run this query inside a loop. I've seen developers drop this logic into a trigger for-loop and hit SOQL limits within minutes of going live. Fetch the session data once at the start of your service class and then reuse it.

Best practices for handling IP data

Just because you can track an Apex user IP address doesn't mean you should. Before you start stamping IP addresses on every record in your org, check with your legal team. Between GDPR and CCPA, storing PII (Personally Identifiable Information) like a specific IP can turn into a compliance headache.

Then there's choosing the right tool for the job. If you only need this on one screen, a simple LWC may be the better fit. If you need the data persisted through a complex transaction, Apex wins. Either way, bulkify the logic when you're processing multiple records at once.

Key takeaways

  • Use Auth.SessionManagement.getCurrentSession() to get the Apex user IP address.
  • The LoginGeo object is where the city and country data lives.
  • Always use Test.isRunningTest() guards since sessions don't exist in test context.
  • Be mindful of privacy laws like GDPR before storing location data permanently.
  • Check for nulls at every step, because not every login has a geo-record.

Getting the Apex user IP address is a straightforward way to add a layer of security or personalization to your org. It's a tool I keep in my back pocket for any project involving sensitive data or regional business logic. Keep your code clean, watch your limits, and respect user privacy.

Frequently asked questions

How do you get a user IP address in Apex?

Call Auth.SessionManagement.getCurrentSession() to get the session map and read the SourceIp key. Wrap that call in a Test.isRunningTest() check so unit tests, which have no active session, still run.

How do you get user location details in Apex without an external service?

Take the LoginHistoryId from Auth.SessionManagement.getCurrentSession(), query LoginHistory for its LoginGeoId lookup, then query the LoginGeo object for fields such as City, Subdivision, Country, and PostalCode.

Why is LoginGeo data null for a user session?

The location fields come back empty when the user is on a VPN, or when Salesforce has not mapped that IP range. Check LoginHistoryId, LoginGeoId, and the LoginGeo record itself for null, or you will hit a NullPointerException.

Can you query LoginGeo inside an Apex trigger loop?

No. Querying LoginHistory or LoginGeo inside a trigger loop can push your code into SOQL limits. Query the session data once in a service class and reuse the values across every record you process.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment