How to get Current User IP Address and Location Using Apex

How to get Current User IP Address and Location Using Apex Salesforce Shastras

In Salesforce, capturing and updating the IP address and location of users can be crucial for various business needs, such as security audits, logging, and personalizing user experiences. In this blog post, we’ll walk through a practical example of how to get Current User IP Address and Location Using Apex

Overview

We’ll create an Apex method that:

  1. Retrieves the current user’s IP address.
  2. Fetches the geographical details associated with the user’s login.
  3. Updates a list of accounts records with the retrieved IP address and location.

Step-by-Step Guide

Step 1: Retrieve the User’s IP Address

Salesforce allows us to access session details through the Auth.SessionManagement class. We can use this to get the current session’s IP address.

String sourceIp = !Test.isRunningTest() ? Auth.SessionManagement.getCurrentSession().get('SourceIp') : '';
  • Auth.SessionManagement.getCurrentSession().get('SourceIp') fetches the IP address.
  • The Test.isRunningTest() check ensures that the code behaves correctly during test execution.

Step 2: Fetch Login History and Geo Information

Next, we need to get the geographical details of the user’s login. This involves querying the LoginHistory and LoginGeo objects.

Set<String> historyIds = new Set<String>();
LoginGeo currentGeo;
String sessionLoginId = !Test.isRunningTest() ? Auth.SessionManagement.getCurrentSession().get('LoginHistoryId') : '';

// Query LoginHistory to get the LoginGeoId
for (LoginHistory history : [SELECT Id, LoginGeoId FROM LoginHistory WHERE Id = :sessionLoginId]) {
    historyIds.add(history.LoginGeoId);
}

// Query LoginGeo to get the geographical details
for (LoginGeo geo : [SELECT Id, Subdivision, PostalCode, City, Country FROM LoginGeo WHERE Id IN :historyIds LIMIT 1]) {
    currentGeo = geo;
}
  • We first retrieve the LoginHistoryId from the current session.
  • We then query the LoginHistory object to get the LoginGeoId.
  • Finally, we query the LoginGeo object to get the location details such as Subdivision, PostalCode, City, and Country.

Step 3: Update Account

With the IP address and location details in hand, we can now update the account records. You can create two custom fields: User_IP_Address__c (Text), User_Location__c (Text)

String sourceIp = !Test.isRunningTest() ? Auth.SessionManagement.getCurrentSession().get('SourceIp') : '';
  • Auth.SessionManagement.getCurrentSession().get('SourceIp') fetches the IP address.
  • The Test.isRunningTest() check ensures that the code behaves correctly during test execution.

Step 2: Fetch Login History and Geo Information

Next, we need to get the geographical details of the user’s login. This involves querying the LoginHistory and LoginGeo objects.

Set<String> historyIds = new Set<String>();
LoginGeo currentGeo;
String sessionLoginId = !Test.isRunningTest() ? Auth.SessionManagement.getCurrentSession().get('LoginHistoryId') : '';

// Query LoginHistory to get the LoginGeoId
for (LoginHistory history : [SELECT Id, LoginGeoId FROM LoginHistory WHERE Id = :sessionLoginId]) {
    historyIds.add(history.LoginGeoId);
}

// Query LoginGeo to get the geographical details
for (LoginGeo geo : [SELECT Id, Subdivision, PostalCode, City, Country FROM LoginGeo WHERE Id IN :historyIds LIMIT 1]) {
    currentGeo = geo;
}
  • We first retrieve the LoginHistoryId from the current session.
  • We then query the LoginHistory object to get the LoginGeoId.
  • Finally, we query the LoginGeo object to get the location details such as Subdivision, PostalCode, City, and Country.

Step 3: Update Accounts

With the IP address and location details in hand, we can now update the Account records.

if (currentGeo != null) {
    for (Account accountRec : newAccounts) {
        accountRec.User_IP_Address__c = sourceIp;
        accountRec.User_Location__c = currentGeo.Subdivision + ' ' + currentGeo.PostalCode + ' ' + currentGeo.City + ' ' + currentGeo.Country;
    }
}
  • We check if currentGeo is not null to ensure we have valid location data.
  • We then update each account in the newAccounts list with the IP address and formatted location details.

Complete Code

Here’s the complete method for updating the IP address and location of accounts:

public void updateAccountsIPandLocation(List<Account> newAccounts) {
    // Get the source IP address from the current session
    String sourceIp = !Test.isRunningTest() ? Auth.SessionManagement.getCurrentSession().get('SourceIp') : '';
    
    Set<String> historyIds = new Set<String>();
    LoginGeo currentGeo;
    // Get the current session's LoginHistoryId
    String sessionLoginId = !Test.isRunningTest() ? Auth.SessionManagement.getCurrentSession().get('LoginHistoryId') : '';
    
    // Query LoginHistory to get the LoginGeoId
    for (LoginHistory history : [SELECT Id, LoginGeoId FROM LoginHistory WHERE Id = :sessionLoginId]) {
        historyIds.add(history.LoginGeoId);
    }
    
    // Query LoginGeo to get the geographical details
    for (LoginGeo geo : [SELECT Id, Subdivision, PostalCode, City, Country FROM LoginGeo WHERE Id IN :historyIds LIMIT 1]) {
        currentGeo = geo;
    }
    
    // Update Account with IP address and location details
    if (currentGeo != null) {
        for (Account accountRec : newAccounts) {
            accountRec.User_IP_Address__c = sourceIp;
            accountRec.User_Location__c = currentGeo.Subdivision + ' ' + currentGeo.PostalCode + ' ' + currentGeo.City + ' ' + currentGeo.Country;
        }
    }
}

Conclusion

By following these steps, you can efficiently capture and update the IP address and location of users in Salesforce. This approach can be particularly useful for enhancing security measures and personalizing user experiences.

Feel free to customize the code and approach based on your specific requirements. Happy coding! 🚀


I hope this helps! If you have any questions or need further assistance, feel free to ask. 😊

Leave a Reply

Your email address will not be published. Required fields are marked *