Code ví dụ JSP Servlet đăng nhập (login) bằng Linkedin
(Xem thêm: code ví dụ JSP Servlet login bằng Facebook)
(Xem thêm: Code ví dụ JSP Servlet login bằng Google (Gmail/Google+))
Tạo một ứng dụng trên LinkedIn.
(Xem lại: Tạo ứng dụng Linkedin để đăng nhập thay tài khoản)
Ở đây mình tạo ứng dụng “stackjava.com – JSPServlet” với Client ID = “81b7a9xubzdq1u” và Client Secret = “anbyTSAldwhA28GY”
Code ví dụ JSP Servlet đăng nhập (login) bằng Linkedin stackjava.com
Tạo ứng dụng Java Web với JSP – Servlet
Ở đây mình dùng server là tomcat 8
Mình dùng thư viện org.apache.httpcomponents (httpclient, httpcore, fluent) để gửi request từ bên trong class servlet, thư viện gson để convert dữ liệu từ dạng json và ngược lại. (mấy chức năng này viết khá dài nên mình dùng thư viên cho nhanh)
(Download các thư viện trên tại đây)
Class Constants.java:
Dùng để lưu client_id, client_secret, redirect_uri của ứng dung “stackjava.com – JSPServlet”
package stackjava.com.accesslinkedin.common; public class Constants { public static String LINKEDIN_CLIENT_ID = "81b7a9xubzdq1u"; public static String LINKEDIN_CLIENT_SECRET = "anbyTSAldwhA28GY"; public static String LINKEDIN_REDIRECT_URI = "http://localhost:8080/AccessLinkedIn/login-linkedin"; public static String LINKEDIN_LINK_GET_TOKEN = "https://www.linkedin.com/oauth/v2/accessToken"; public static String LINKEDIN_GRANT_TYPE = "authorization_code"; public static String LINKEDIN_LINK_GET_USER_INFO = "https://api.linkedin.com/v1/people/~?format=json&oauth2_access_token="; }
Trang login
<html> <head> <title>Login</title> </head> <body> <h1>Demo Login with LinkedIn</h1> <a href="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=81b7a9xubzdq1u &redirect_uri=http://localhost:8080/AccessLinkedIn/login-linkedin&scope=r_basicprofile">Login With Linkedin</a> </body> </html>
Đường link https://www.linkedin.com/oauth/v2/...scope=r_basicprofile
dùng để gọi hộp thoại đăng nhập và cài đặt URL chuyển hướng:
Sau khi bạn cho phép ứng dụng truy cập các thông tin tài khoản của LinkedIn, LinkedIn sẽ gửi một đoạn mã (code) tới url “http://localhost:8080/AccessLinkedIn/login-linkedin” để server của bạn xử lý.
- Nếu bạn đồng ý thì redirect uri trả về sẽ có 2 tham số code (OAuth 2.0 authorization code) và state ( dùng cho CRSF)
- Nếu bạn không đồng ý thì redirect uri trả về sẽ kèm 3 than số là error_code, error_description và state
Class Servlet
package stackjava.com.accesslinkedin.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import stackjava.com.accesslinkedin.common.User; import stackjava.com.accesslinkedin.common.LinkedInUtils; @WebServlet("/login-linkedin") public class LoginLinkedinServlet extends HttpServlet { private static final long serialVersionUID = 1L; public LoginLinkedinServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String code = request.getParameter("code"); if (code == null || code.isEmpty()) { RequestDispatcher dis = request.getRequestDispatcher("login.jsp"); dis.forward(request, response); } else { String accessToken = LinkedInUtils.getToken(code); User user = LinkedInUtils.getUserInfo(accessToken); request.setAttribute("id", user.getId()); request.setAttribute("name", user.getName()); RequestDispatcher dis = request.getRequestDispatcher("index.jsp"); dis.forward(request, response); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
LoginLinkedinServlet.java sẽ nhận đoạn mã trả về từ linkedin, đổi mã đó thành access-token rồi dùng access-token để truy cập các thông tin trong tài khoản linkedin như name, id…
Class LinkedInUtils.java dùng để gửi truy vấn tới linkedin (đổi code sang access-token, lấy thông tin trong tài khoản linkedin)
package stackjava.com.accesslinkedin.common; import java.io.IOException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.fluent.Form; import org.apache.http.client.fluent.Request; import com.google.gson.Gson; import com.google.gson.JsonObject; public class LinkedInUtils { public static String getToken(final String code) throws ClientProtocolException, IOException { String response = Request.Post(Constants.LINKEDIN_LINK_GET_TOKEN) .bodyForm(Form.form().add("client_id", Constants.LINKEDIN_CLIENT_ID) .add("client_secret", Constants.LINKEDIN_CLIENT_SECRET) .add("redirect_uri", Constants.LINKEDIN_REDIRECT_URI).add("code", code) .add("grant_type", Constants.LINKEDIN_GRANT_TYPE).build()) .execute().returnContent().asString(); JsonObject jobj = new Gson().fromJson(response, JsonObject.class); String accessToken = jobj.get("access_token").toString().replaceAll("\"", ""); return accessToken; } public static User getUserInfo(final String accessToken) throws ClientProtocolException, IOException { String link = Constants.LINKEDIN_LINK_GET_USER_INFO + accessToken; String response = Request.Get(link).execute().returnContent().asString(); JsonObject jobj = new Gson().fromJson(response, JsonObject.class); String id = jobj.get("id").toString().replaceAll("\"", ""); String firstName = jobj.get("firstName").toString().replaceAll("\"", ""); String lastName = jobj.get("lastName").toString().replaceAll("\"", ""); String name = firstName + lastName; User user = new User(id, name); return user; } }
Đường link lấy thông tin tài khoản linkedin sẽ có dạng:
https://api.linkedin.com/v1/people/~?format=json&oauth2_access_token=your_accesstoken
Thông tin trả về tùy vào permission mà ứng dụng được cấp, ở đây mình chỉ yêu cầu permission là r_basicprofile nên thông tin trả về sẽ gồm:
{ "firstName": "...", "headline": "...", "id": "...", "lastName": "...", "siteStandardProfileRequest": { "url": "https://www.linkedin.com/profile/view?id=…" } }
Class User.java để lưu thông tin tài khoản từ linkedin
package stackjava.com.accesslinkedin.common; public class User { private String id; private String name; // getter - setter }
Trang index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <title>index</title> </head> <body> <h1>Index</h1> <% String id = request.getAttribute("id").toString(); String name = request.getAttribute("name").toString(); out.print("Id: " + id); out.print("<br/>Name: " + name); %> </body> </html>
Demo:
Trường hợp không cho phép ứng dụng “stackjava.com – JSPServlet” truy cập thông tin tài khoản:
Trường hợp cho phép ứng dụng “stackjava.com – JSPServlet” truy cập thông tin tài khoản:
Code ví dụ JSP Servlet đăng nhập (login) bằng Linkedin stackjava.com
Okay, Done!
Download code ví dụ trên tại đây.
References.
https://developer.linkedin.com/docs/oauth2
https://developer.linkedin.com/docs/signin-with-linkedin#