ZOFTINO.COM android and web dev tutorials

How to Implement Google Plus Login for Websites Using Oauth2 in Java

Providing an option of login with Google plus is useful for your website and users because most people have Google plus account and they don’t need to create one more account for your website. And also chance of your users enrolling for your website’s restricted features will increase with Google plus login option.

I am going to show how to implement Google Plus login from server side using OAuth 2.0. If you need to implement Facbook login for your website, check Facebook login for websites.

For server side implementation, we need any http client to call Google APIs. As I used RestFB framework for facebook login intergration, I’ll use same http client for calling Google APIs. So there is no need to include one more jar as RestFB jar can be used for both Facebook and Google plus login integrations.

Below are the steps to implement Google Plus login integration.

  1. Login to Google API console, create project, client id and client secret.
  2. Add redirect urls (your website urls) in API console.
  3. Your server side code which handles Login-With-Google+ button action, redirects the user to below Google outh2 endpoint url if user is not already logged in. In this url, you need to pass client id which you created in API console, scope parameter is for permission, state parameter is used to prevent cross site request forgery by sending unique string and response_type parameter with code as value is sent so that Google oauth2 endpoint sends authorization code in response.

    https://accounts.google.com/o/oauth2/auth?scope=email%20profile&redirect_uri=your domain%2Faccount%2Fgpsignin&response_type=code& client_id=clientid&state=

  4. Google oauth2 server authenticates user, gets requested permissions for your application from user and sends response to the redirect url passed in the login url.
  5. The action which handles the redirect url in your application, need to first match the state returned in above response with state from your application session. This is required to prevent cross site request forgery.
  6. Using http client you need to post request to below Google oauth2 token endpoint. You need to pass clientid, client _secret, redirect_uri, grant_type and code which is received in login response above step.

    https://www.googleapis.com/oauth2/v4/token?client_id=clientid&client_secret=client secret&redirect_uri=yourdomain%2Faccount%2Fgpsignin& grant_type=authorization_code&code=

  7. Token endpoint sends access token in response. Response is sent in JSON format
  8. Using above access token, you need to send below http get request to get users details.

    https://www.googleapis.com/plus/v1/people/me?access_token=

  9. If you need to identify user in your application, you need to add user details in your app when user logins first time using Google plus authentication
  10. Logout action should invalidate both your application session and Google oauth2 token. Logout action needs to be redirected to below Google url to log user out from Google.

    https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=yourdomain%2Faccount%2Flogout

Below is the java code to implement Google+ login for websites.

	@RequestMapping(value = "/account/gpsignin", method = RequestMethod.GET)
	public String googlePlusLogin(HttpServletRequest request, ModelMap model){

		String gpappsec = "client serect";
		String gptokenurl = "https://www.googleapis.com/oauth2/v4/token";
		String gpUserUrl = "https://www.googleapis.com/plus/v1/people/me?access_token=";

		String gpsigninUrl = "https://accounts.google.com/o/oauth2/auth?scope=email%20profile&redirect_uri=yourdomain%2Faccount%2Fgpsignin&response_type=code&client_id=clientid&state=";
		String gptokenParms = "client_id=clientid&client_secret="+gpappsec+"&redirect_uri=yourdomain%2Faccount%2Fgpsignin&grant_type=authorization_code&code=";


		//user already logged in?
		if(!("anonymousUser".equals(SecurityContextHolder.getContext().getAuthentication().getName()))){
			return "redirect:/myinfo.htm";
		}
		String gpcode =  request.getParameter("code");
		String state =  request.getParameter("state");

		if(StringUtils.isEmpty(state) || StringUtils.isEmpty(gpcode)){
			String statekey = RandomStringUtils.randomAlphanumeric(40);
			request.getSession().setAttribute("gpstate", statekey);
			return "redirect:"+gpsigninUrl+statekey;				
		}else{
			String statekey = (String)request.getSession().getAttribute("gpstate");
			if(!state.equals(statekey)){
				model.addAttribute("errormsglg","Login error");	
				return "login";
			}

			FacebookClient fbclient = new DefaultFacebookClient(Version.VERSION_2_3);
			try {
				Response fbrs = fbclient.getWebRequestor().executePost(gptokenurl, gptokenParms+gpcode);
				if(fbrs.getStatusCode() != 200){
					model.addAttribute("errormsglg","Login error");	
					return "login";
				}
				JsonObject json = new JsonObject(fbrs.getBody().toString());

				request.getSession().setAttribute("usergpacesstoken", json.getString("access_token"));

				Response fbrs2 = fbclient.getWebRequestor().executeGet(gpUserUrl+json.getString("access_token"));
				JsonObject juser = new JsonObject(fbrs2.getBody().toString());
				JsonArray emails = juser.getJsonArray("emails");
				String gpemailId = "";
				
				for ( int j=0; j < emails.length(); j++) {
					
					JsonObject emailtype = new JsonObject(emails.getString(j));
					
					String emailType = emailtype.getString("type");
					
					if(emailType.equals("account")){
						gpemailId = emailtype.getString("value");
						break;
					}
				}
				processSocialLogin(juser.getString("id"),gpemailId, juser.getString("displayName"),
						"GP",json.getString("access_token"),request);

			} catch (Exception e) {
				model.addAttribute("errormsglg","Login error");	
				return "login";
			}

		}			
		return "redirect:myinfo.htm";
	}