1. 我們的的操作流程:
用戶在我們系統登錄頁面,不用點注冊或者登錄,而是點擊Gitee圖標(如下圖),跳轉到Gitee的登錄頁,登陸后點擊授權按鈕,然后獲得授權碼,然后跳轉回我們的系統,,我們用這個授權碼獲取Token,成功獲取到Token后,利用token獲取Gitee用戶信息,然后,把這個userinfo,注冊或者登錄我們自己的系統(如果這個社交賬號之前沒有登陸過,就自動注冊並登錄,根據Gitee返回的ID判斷),
我們這次的OAuth2,使用授權碼方式
2. 首先我們登錄自己的Gitee,在自己的設置頁面中,進入第三方應用,並新建一個應用,應用名稱和圖標,就是我們自己的系統
3. 創建好應用后,記住自己的Client ID和Client Secret,然后還有一個重要的東西是設置好自己的應用回調地址,這個就是用戶在gitee點擊授權后,Gitee把授權碼給我們系統的哪個接口。注意,接口要接收code,
@RequestParam("code") String code
4. 現在把gitee小圖標放到我們的登錄頁,img外面包一層a標簽,點擊后跳轉到下面這個地址
https://gitee.com/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code
注意,把地址中的Client ID和redirect_uri替換為,你在第三步設置和獲得的值。
5.現在用戶點擊圖標就會去gitee,登錄授權后,就會去我們的回調地址,也就是controller接口,而且會帶一個授權碼code,這個code,我們就可以拿着去換token,然后拿着Token獲取用戶信息,然后拿着這個用戶信息,我們就可以幫用戶登錄或者注冊了
這里我把我的回調地址接口貼上來,也把Token和用戶信息,映射的實體也貼上來。我把httpUitl這個工具類也貼上來
1 @GetMapping("/oauth2.0/gitee/success") 2 public String gitee(@RequestParam("code") String code) throws Exception { 3 Map<String,String> bodys = new HashMap<>(); 4 bodys.put("grant_type","authorization_code"); 5 bodys.put("code",code); 6 bodys.put("client_id","你的在第三步獲取的client_id"); 7 bodys.put("redirect_uri","你在第三步寫的回調地址"); 8 bodys.put("client_secret","你在第三步寫的client_secret"); 9 //1.根據code換取GiteeAccessToken; 10 HttpResponse response_GiteeAccesstoken = HttpUtils.doPost("https://gitee.com", "/oauth/token", "post", new HashMap(), new HashMap(), bodys); 11 12 //處理返回值 13 if(response_GiteeAccesstoken.getStatusLine().getStatusCode() == 200){ 14 //獲取到了GiteeAccessToken 15 String tokenJson = EntityUtils.toString(response_GiteeAccesstoken.getEntity()); 16 GiteeAccessToken token = JSON.parseObject(tokenJson, GiteeAccessToken.class); 17 //根據Token,通過查詢Gitee Open Api獲取用戶信息 18 Map<String,String> query = new HashMap<>(); 19 query.put("access_token", token.getAccess_token()); 20 HttpResponse response_userInfo = HttpUtils.doGet("https://gitee.com", "/api/v5/user", "get", new HashMap(), query); 21 String giteeUserInfoJson = EntityUtils.toString(response_userInfo.getEntity()); 22 GiteeUserInfo giteeUserInfo = JSON.parseObject(giteeUserInfoJson, GiteeUserInfo.class); 23 24 //登錄或者注冊這個社交用戶 25 //1.當前用戶如果是第一次進入網站,就自動注冊(為當前社交用戶生成一個會員信息賬號,以后這個社交賬號就對應指定的會員) 26 27 }else { 28 return "redirect:http://auth.gulimall.com/login.html"; 29 } 30 31 //2.登錄成功后跳回首頁 32 return "redirect:http://gulimall.com"; 33 }
token的java映射實體
public class GiteeAccessToken { private String access_token; private String token_type; private long expires_in; private String refresh_token; private String scope; private long created_at; }
用戶信息的映射實體
public class GiteeUserInfo { private long id; private String login; private String name; private String avatar_url; private String url; private String html_url; private String followers_url; private String following_url; private String gists_url; private String starred_url; private String subscriptions_url; private String organizations_url; private String repos_url; private String events_url; private String received_events_url; private String type; private String blog; private String weibo; private String bio; private long public_repos; private long public_gists; private long followers; private long following; private long stared; private long watched; private String created_at; private String updated_at; private String email; }
HttpUtils工具類
import org.apache.commons.lang.StringUtils; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @author sunziren * @date 2021/8/13 16:10 */ public class HttpUtils { /** * get * * @param host * @param path * @param method * @param headers * @param querys * @return * @throws Exception */ public static HttpResponse doGet(String host, String path, String method, Map<String, String> headers, Map<String, String> querys) throws Exception { HttpClient httpClient = wrapClient(host); HttpGet request = new HttpGet(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } return httpClient.execute(request); } /** * post form * * @param host * @param path * @param method * @param headers * @param querys * @param bodys * @return * @throws Exception */ public static HttpResponse doPost(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, Map<String, String> bodys) throws Exception { HttpClient httpClient = wrapClient(host); HttpPost request = new HttpPost(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } if (bodys != null) { List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>(); for (String key : bodys.keySet()) { nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key))); } UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8"); formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); request.setEntity(formEntity); } return httpClient.execute(request); } /** * Post String * * @param host * @param path * @param method * @param headers * @param querys * @param body * @return * @throws Exception */ public static HttpResponse doPost(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, String body) throws Exception { HttpClient httpClient = wrapClient(host); HttpPost request = new HttpPost(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } if (StringUtils.isNotBlank(body)) { request.setEntity(new StringEntity(body, "utf-8")); } return httpClient.execute(request); } /** * Post stream * * @param host * @param path * @param method * @param headers * @param querys * @param body * @return * @throws Exception */ public static HttpResponse doPost(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, byte[] body) throws Exception { HttpClient httpClient = wrapClient(host); HttpPost request = new HttpPost(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } if (body != null) { request.setEntity(new ByteArrayEntity(body)); } return httpClient.execute(request); } /** * Put String * @param host * @param path * @param method * @param headers * @param querys * @param body * @return * @throws Exception */ public static HttpResponse doPut(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, String body) throws Exception { HttpClient httpClient = wrapClient(host); HttpPut request = new HttpPut(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } if (StringUtils.isNotBlank(body)) { request.setEntity(new StringEntity(body, "utf-8")); } return httpClient.execute(request); } /** * Put stream * @param host * @param path * @param method * @param headers * @param querys * @param body * @return * @throws Exception */ public static HttpResponse doPut(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, byte[] body) throws Exception { HttpClient httpClient = wrapClient(host); HttpPut request = new HttpPut(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } if (body != null) { request.setEntity(new ByteArrayEntity(body)); } return httpClient.execute(request); } /** * Delete * * @param host * @param path * @param method * @param headers * @param querys * @return * @throws Exception */ public static HttpResponse doDelete(String host, String path, String method, Map<String, String> headers, Map<String, String> querys) throws Exception { HttpClient httpClient = wrapClient(host); HttpDelete request = new HttpDelete(buildUrl(host, path, querys)); for (Map.Entry<String, String> e : headers.entrySet()) { request.addHeader(e.getKey(), e.getValue()); } return httpClient.execute(request); } private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException { StringBuilder sbUrl = new StringBuilder(); sbUrl.append(host); if (!StringUtils.isBlank(path)) { sbUrl.append(path); } if (null != querys) { StringBuilder sbQuery = new StringBuilder(); for (Map.Entry<String, String> query : querys.entrySet()) { if (0 < sbQuery.length()) { sbQuery.append("&"); } if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) { sbQuery.append(query.getValue()); } if (!StringUtils.isBlank(query.getKey())) { sbQuery.append(query.getKey()); if (!StringUtils.isBlank(query.getValue())) { sbQuery.append("="); sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8")); } } } if (0 < sbQuery.length()) { sbUrl.append("?").append(sbQuery); } } return sbUrl.toString(); } private static HttpClient wrapClient(String host) { HttpClient httpClient = new DefaultHttpClient(); if (host.startsWith("https://")) { sslClient(httpClient); } return httpClient; } private static void sslClient(HttpClient httpClient) { try { SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] xcs, String str) { } public void checkServerTrusted(X509Certificate[] xcs, String str) { } }; ctx.init(null, new TrustManager[] { tm }, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx); ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); ClientConnectionManager ccm = httpClient.getConnectionManager(); SchemeRegistry registry = ccm.getSchemeRegistry(); registry.register(new Scheme("https", 443, ssf)); } catch (KeyManagementException ex) { throw new RuntimeException(ex); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } } }
工具類需要引入的依賴
<!-- 引入HttpUtils 開始 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.15</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.2.1</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.2.1</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util</artifactId> <version>9.3.7.v20160115</version> </dependency> <!-- 引入HttpUtils 結束 -->