天天看點

LinkedIn登入第三方網站

參考:

https://developer.linkedin.com/docs/oauth2

https://developer.linkedin.com/docs/signin-with-linkedin

準備工作:

注冊一個開發号在建立一個Web應用,網址: https://www.linkedin.com/developer/apps

需求:點選使用linkedIn登入圖示,調轉到linkedIn授權頁面。點選允許登入網址。

開發:

第一步擷取Code:

Controller:

@RequestMapping(value = "/toLogin")
	public void weixinLogin(HttpServletRequest request,HttpServletResponse response){
		String appid=PropertiesUtils.getProperty("system.linkedIn.clientId");
		int serverPost = request.getServerPort();
		String basePath = null;
    	if(serverPost==80){
    		basePath = request.getScheme()+"://"+request.getServerName()+request.getContextPath();
    	}else{
    		basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();
    	}
		String redirectUri=basePath+"/linkedIn/loginProcess";
		String code="code";
		String state=MyTools.generateString(20);
		HttpSession session = request.getSession();
		session.setAttribute("linkcode", state);
		String baseUrl="https://www.linkedin.com/oauth/v2/authorization";
		linkedInHelper.toLoginPage(baseUrl, appid, redirectUri, code, "", state,response);
	}
           

LinkedInAPI.java:

public boolean toLoginPage(String baseUrl,String clientId,String redirectUri,String code,String scope,String state,HttpServletResponse response){
		try {
			String redirectUriCode = URLEncoder.encode(redirectUri,"utf-8");//坑1
			baseUrl+="?client_id="+clientId+"&redirect_uri="+redirectUriCode+"&response_type="+code+"&scope="+scope+"&state="+state+"&format=json";
			try {
				response.sendRedirect(baseUrl);
			} catch (IOException e) {
				log.error("URLEncoder重定向位址失敗,請求取消");
				e.printStackTrace();
				return false;
			}
			return true;
		} catch (UnsupportedEncodingException e) {
			log.error("URLEncoder重定向位址失敗,請求取消");
			e.printStackTrace();
			return false;
		}
	}
           

第二步擷取Token,然後擷取使用者資訊登入網址:

@RequestMapping(value = "/loginProcess")
	public ModelAndView LoginProcess( HttpServletRequest request){
		ModelAndView mav=new ModelAndView();
		String code=request.getParameter("code");
		String status=request.getParameter("state");
		String tempCode=(String)request.getSession().getAttribute("linkcode");
		request.getSession().removeAttribute("linkcode");
		/*防止跨站攻擊*/
		if(null==tempCode||null==status||!tempCode.trim().equalsIgnoreCase(status.trim())){
			mav.setViewName("/error404");
			mav.addObject("msg", "疑似跨站攻擊");
			return mav;
		}
		/*判斷第一步是否得到Code*/
		if(MyTools.isEmptyStr(code)){
			//登入失敗處理
			mav.setViewName("/error404");
			String errorDes=request.getParameter("error_description");
			mav.addObject("msg",errorDes);
			return mav;
		}else{
			String appid=PropertiesUtils.getProperty("system.linkedIn.clientId");
			String secret=PropertiesUtils.getProperty("system.linkedIn.clientSecret");
			String getTokenUrl="https://www.linkedin.com/oauth/v2/accessToken";
			int serverPost = request.getServerPort();
			String basePath = null;
			if(serverPost==80){
	    		basePath = request.getScheme()+"://"+request.getServerName()+request.getContextPath();
	    	}else{
	    		basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();
	    	}
			String redirectUri=basePath+"/linkedIn/loginProcess";
			JSONObject tokenInfo=linkedInHelper.getAccessToken(getTokenUrl, appid, secret, code, "authorization_code", redirectUri);
			if(null==tokenInfo){
				mav.setViewName("/error404");
				mav.addObject("msg", "HTTP請求出錯!");
				return mav;
			}
			if(!tokenInfo.containsKey("access_token")){
				/*擷取Token失敗處理*/
				//登入失敗處理
				mav.setViewName("/error404");
				mav.addObject("msg","擷取令牌失敗");
				return mav;
			}else{
				/*用Token擷取使用者資訊*/
				String accessToken=tokenInfo.getString("access_token");
				if(MyTools.isEmptyStr(accessToken)){
					/*擷取Token失敗處理*/
					//登入失敗處理
					mav.setViewName("/error404");
					mav.addObject("msg","擷取令牌失敗");
					return mav;
				}
				String getUserInfoUrl="https://api.linkedin.com/v1/people/~";
				JSONObject userInfo=linkedInHelper.getUserInfo(getUserInfoUrl, accessToken);
				if(!userInfo.containsKey("id")){
					/*擷取資訊失敗*/
					mav.setViewName("/error404");
					mav.addObject("msg", tokenInfo.get("errmsg"));
					return mav;
				}else{
					/*擷取資訊成功*/
					//儲存使用者
					UserInfo user=new UserInfo();
					user.setName(userInfo.getString("firstName")+" "+userInfo.getString("lastName"));
					user.setUid(userInfo.getString("id"));
					user.setLinkedInId(userInfo.getString("id"));
					user.setCreateDate(new Date());
					user.setEnabled(1);
					user.setType(1);
					user.setRegisterSource(2);
					user.setRegisterCode(MyTools.generateString(30));
					userService.saveUserInfo(user);
					InsideUsernamePasswordToken token = new InsideUsernamePasswordToken();
					token.setUsername(userInfo.getString("id"));
					//****—****#####登入處理代碼
					token.setRememberMe(false);
					Subject subject = SecurityUtils.getSubject();
					subject.login(token);
					mav.setViewName("redirect:/index");
					return mav;
				}
			}
		}
	}
           

LinkedInAPI:

/**
	 * 擷取令牌
	 * @param baseUrl
	 * @param clientId
	 * @param secret
	 * @param code 第一步中得到的
	 * @param grantType 填authorization_code
	 * @param redirectUri
	 * @return access_token and expires_in
	 * 建立時間:2016年11月9日 下午2:11:11
	 */
	public JSONObject getAccessToken(String baseUrl,String clientId,String secret,String code,String grantType,String redirectUri){
		try {
		String redirectUriCode = URLEncoder.encode(redirectUri,"utf-8");//對應坑1
		baseUrl+="?client_id="+clientId+"&client_secret="+secret+"&code="+code+"&grant_type="+grantType+"&redirect_uri="+redirectUriCode+"&format=json";
		String resultJson=HttpHelper.doPostForLinkedIn(baseUrl,"");
		return JSONObject.parseObject(resultJson);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		
	}
           
/**
	 * 擷取使用者的基本資訊
	 * @param baseUrl
	 * @param accessToken
	 * @return 
	 * 建立時間:2016年11月9日 下午3:29:29
	 */
	public JSONObject getUserInfo(String baseUrl,String accessToken){
		String resultJson=HttpHelper.doGet(baseUrl+"?"+"format=json","Bearer "+accessToken);//坑2,token放到這裡
		return JSONObject.parseObject(resultJson);
	}
           

HttpHelper.java

public static String doGet(String strURL,String authorizationStr){
		String result="";
		try{
			URL url = new URL(strURL);// 建立連接配接
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setUseCaches(false);
			connection.setRequestMethod("GET"); // 設定請求方式
			connection.setRequestProperty("Accept", "application/json"); // 設定接收資料的格式
			connection.setRequestProperty("Content-Type", "application/json"); // 設定發送資料的格式
			connection.setRequestProperty("Authorization",authorizationStr);//對應坑2,token放到這裡
			connection.connect();
			// 處理響應資料
			BufferedReader in = null;
			try {
				 in = new BufferedReader(new InputStreamReader(
						connection.getInputStream()));
				String line;
				while ((line = in.readLine()) != null) {
					result += line;
				}
			} finally {
				if(in!=null) in.close();
			}
		}catch(Exception e){
			StackTraceElement stes[]=e.getStackTrace();
			log.info(HttpHelper.class.toString()+"function:doGet");
			log.info("---------------------http請求位址-----------------------");
			log.info(strURL);
			log.info("---------------------http請求内容-----------------------");
			log.info(result);
			for(StackTraceElement ste:stes){
				log.error(ste.getFileName()+":"+ste.getLineNumber()+":"+ste.getMethodName());
			}
		}
		return result;
	}
	public static String doPostForLinkedIn(String strURL, String jsonParams){   
		String result = "";
		try{
			URL url = new URL(strURL);// 建立連接配接
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			// connection.setInstanceFollowRedirects(true);
			connection.setRequestMethod("POST"); // 設定請求方式
			//坑3 application/x-www-form-urlencoded
			connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // 設定發送資料的格式
			connection.connect();
			PrintWriter out = new PrintWriter(connection.getOutputStream());
			System.out.println("helper==="+jsonParams+"===");
			try {
				out.print(jsonParams);
				out.flush();
			} finally {
				if(out!=null) out.close();
			}
			// 處理響應資料
			BufferedReader in = null;
			try {
				in = new BufferedReader(new InputStreamReader(
						connection.getInputStream()));
				String line;
				while ((line = in.readLine()) != null) {
					result += line;
				}
			} finally {
				if(in!=null) in.close();
			}
		}catch(Exception e){
			log.info(HttpHelper.class.toString());
			log.info("---------------------http請求位址-----------------------");
			log.info(strURL);
			log.info("---------------------http請求内容-----------------------");
			log.info(result);
			StackTraceElement stes[]=e.getStackTrace();
			for(StackTraceElement ste:stes){
				log.error(ste.getFileName()+":"+ste.getLineNumber()+":"+ste.getMethodName());
			}
			e.printStackTrace();
		}
		return result;
	}