Loading
Salesforce now sends email only from verified domains. Read More
Identify Your Users and Manage Access
Table of Contents
Select Filters

          No results
          No results
          Here are some search tips

          Check the spelling of your keywords.
          Use more general search terms.
          Select fewer filters to broaden your search.

          Search all of Salesforce Help
          Create an Embedded Login Server-Side Callback

          Create an Embedded Login Server-Side Callback

          Use the server-side callback instead of a client-side callback web page to avoid exposing the access token on the client. To create a server-side callback, use the OAuth 2.0 web server flow.

          Warning
          Warning In Summer ’24, Salesforce made Embedded Login disabled by default. We recommend that you use the web server flow, the user-agent flow, or another redirect-based OAuth 2.0 flow instead of Embedded Login.

          Embedded Login relies on third-party cookies, which are blocked or restricted in most browsers. And Embedded Login works only on Google Chrome and only as long as third-party cookies are allowed there by default.

          When you use the server-side callback, create a separate servlet that implements the web server flow using the OAuth 2.0 authorization code grant type.

          Use these steps to create the server-side callback servlet.

          1. Implement the web server flow. For detailed steps to implement this flow, see OAuth 2.0 Web Server Flow for Web App Integration.
          2. Create the OAuth response that the Embedded Login posts after successfully receiving an access token.
            The response must contain these meta tags.
            • salesforce-community
            • salesforce-mode (where the value ends in -callback)
              Note
              Note The value of the salesforce-mode meta tag is the same mode specified in the Embedded Login web page with the -callback suffix. For example, if salesforce-mode on the web page is set to modal, the value is modal-callback.
            • salesforce-server-callback (where the value must be true)
            • salesforce-server-response
            • salesforce-server-starturl
              Note
              Note If the Block Redirect to Unknown URL setting is enabled for the site, Salesforce blocks redirects to unknown URLs that are provided in the state parameter of the OAuth response. Redirects are allowed when the URL is in the same host or domain as the site, or is allow-listed in the Embedded Login salesforce-allowed-domains meta tag.
            • salesforce-target
            • salesforce-allowed-domains
            You can include the salesforce-save-access-token with the value true to save the access token after initialization. By saving the access token, you can continue to interact with Salesforce during the active user session.
          3. In your Embedded Login web page, specify these meta tags.
            1. Add the salesforce-server-callback meta tag with the value true. This meta tag indicates that the callback to handle the HTTP response is on the server.
              <meta name="salesforce-server-callback" content="true">
            2. Make sure that the salesforce-redirect-uri meta tag references the location of the server-side callback servlet. Use the same URL as specified in the callback URL field of your Embedded Login external client app.
              <meta name="salesforce-redirect-uri" content="https://embeddedlogin.heroku.com/servlet/servlet.serversidecallback>
            3. Make sure that the salesforce-mode on this web page matches the mode on the server-side callback.
          Example
          Example
          Note
          Note This server callback servlet uses base64 encoding in the server response.
          package servlet;
          
          import org.apache.commons.httpclient.HttpClient;
          import org.apache.commons.httpclient.methods.GetMethod;
          import org.apache.commons.httpclient.methods.PostMethod;
          
          import org.json.JSONObject;
          
          import javax.servlet.ServletConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletOutputStream;
          import javax.servlet.annotation.WebServlet;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          
          import javax.servlet.http.*;
          import java.io.IOException;
          import java.io.PrintWriter;
          import java.net.URLDecoder;
          import java.nio.charset.StandardCharsets;
          import java.util.Base64;
          
          @WebServlet(
                  name = "CallbackServlet2",
                  urlPatterns = {"/_callback"}
              )
          public class ServerSideCallbacks extends HttpServlet{
          
          	// Client ID
              private static final String CLIENT_ID= 
          "3MVG9xOCXq4ID1uF8V6oKd32SPVi6FHwEOQlQ5BjvaKX.5QZpGe4Z3F4fc6KvMYsQ.fi314cp0oZ8KpOBs4Mh";
          
              // client secret
              private static final String CLIENT_SECRET = "9103416584217247123";
              
              @Override
              public void init(ServletConfig config) throws ServletException {
                  super.init(config);
              }
          
              @Override
              protected void doGet(HttpServletRequest request, HttpServletResponse response) 
                  throws 
                  ServletException, IOException {
          
                  String code = request.getParameter("code");
                  if (code != null) {
                      code = URLDecoder.decode(code, "UTF-8");
                  }
                  String startURL = request.getParameter("state");
                  if (startURL != null) {
                      startURL = URLDecoder.decode(startURL, "UTF-8");
                  }
                          
                  String tokenResponse = null;
                  String communityUrl = null;
                  HttpClient httpclient = new HttpClient();
                  try {            
                      // community_url parameter passed from redirect uri.
                      communityUrl = request.getParameter("sfdc_community_url");
                      // Token endpoint : communityUrl + "/services/oauth2/token";
                      PostMethod post = new PostMethod(communityUrl+"/services/oauth2/token");
                      post.addParameter("code",code);
                      post.addParameter("grant_type","authorization_code");
                      // Consumer key of the external client app.
                      post.addParameter("client_id", CLIENT_ID);
                      // Consumer Secret of the external client app.
                      post.addParameter("client_secret",CLIENT_SECRET);
                      
                      // Callback URL of the external client app.
                      post.addParameter("redirect_uri", 
                          "https://boiling-brushlands-41143.herokuapp.com/_callback");
                      
                      httpclient.executeMethod(post);
                      tokenResponse = post.getResponseBodyAsString();
                      post.releaseConnection();
           
                      System.err.println("tokenResponse: " + tokenResponse);
                  } catch (Exception e) {
                  		throw new ServletException(e);
                  }
          
          
                  JSONObject identityJSON = null;
                  try {
                      JSONObject token = new JSONObject(tokenResponse);
                      // get the access token from the response
                      String accessToken = token.getString("access_token");
                      String identity = token.getString("id");
                      httpclient = new HttpClient();
                      GetMethod get = new GetMethod(identity + "?version=latest");
                      get.setFollowRedirects(true);
                      get.addRequestHeader("Authorization", "Bearer " + accessToken);
                      
                      // get identity information using the access token
                      httpclient.executeMethod(get);
                      String identityResponse = get.getResponseBodyAsString();
                      get.releaseConnection();
                      identityJSON = new JSONObject(identityResponse);
                      identityJSON.put("access_token", accessToken);
                  } catch (Exception e) {
                      throw new ServletException(e);
                  }
                  
          
                  response.setContentType("text/html; charset=utf-8");
                  PrintWriter out = response.getWriter();
          
                 //  Notice that we’re using base64 encoded
                  String outputStr =  "<html><head>\n" +
                     "<meta name=\"salesforce-community\" content=\""+ communityUrl +"\">\n" +
                      // notice the -callback in the salesforce-mode content value
          		         "<meta name=\"salesforce-mode\" content=\"modal-callback\">\n" +
                       "<meta name=\"salesforce-server-callback\" content=\"true\">\n" +
          
          		  // send the identity information back to the Embedded Login                
                           "<meta name=\"salesforce-server-response\" content='" + 
                          Base64.getEncoder().encodeToString(identityJSON.toString().
                             getBytes(StandardCharsets.UTF_8))+"'>\n" +
                          "<meta name=\"salesforce-server-starturl\" content='" + startURL +"'>\n" +
                          "<meta name=\"salesforce-target\" content= \"#salesforce-login\">\n"+
                          "<meta name=\"salesforce-allowed-domains\" 
                          content=\"boiling-brushlands-41143.herokuapp.com\">\n" +
                          "<script src=\""+ communityUrl + 
                           "/servlet/servlet.loginwidgetcontroller?type=javascript_widget\"" +
                          " async defer></script>\n" +
                          "</head><body></body></html>";
                  out.write(outputStr);
              }
          
          }
          
           
          Loading
          Salesforce Help | Article