【第三方互聯】九、新浪微博授權第三方登錄

當我們創建的新浪微博互聯應用成功後,我們便可以開始使用該應用來實現新浪微博授權操作

  • 一、獲取 App Key 和 App Secret

1、在“我的應用”,點擊應用,查看我們創建的應用的基本信息
應用基本信息
這樣,我們就獲取到了 App Key 和 App Secret

2、將 App Key 和 App Secret,以及該應用的信息放入項目中的配置文件中,我使用的是SpringBoot,我放在了 application.yml 配置文件中
微博互聯信息

  • 二、添加 Maven 依賴
<!-- 網絡請求 -->
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
	<version>4.5.6</version>
</dependency>

其他依賴,請自行加入

  • 三、在頁面放置 “新浪微博” 授權登錄的 DOM 元素
<a th:href="@{weibo/auth}" class="link" title="新浪微博登錄"><i class="layui-icon">&#xe675;</i></a>
  • 四、創建 “新浪微博” 授權登錄的 Controller,WeiboController.java

1、從配置文件中獲取 “新浪微博” 互聯信息

/**
  * 微博授權中提供的 appid 和 appkey
  */
 @Value("${weibo.oauth.appid}")
 public String APPID;
 @Value("${weibo.oauth.appkey}")
 public String APPKEY;
 @Value("${weibo.oauth.url}")
 public String URL;

定義三個變量,接收 “新浪微博” 互聯的信息

2、登錄按鈕點擊後的接口

/**
  * 請求授權頁面
  */
 @GetMapping(value = "/auth")
 public String qqAuth(HttpSession session) {
     // 用於第三方應用防止CSRF攻擊
     String uuid = UUID.randomUUID().toString().replaceAll("-", "");
     session.setAttribute("state", uuid);

     // Step1:獲取Authorization Code
     String url = "https://api.weibo.com/oauth2/authorize?response_type=code" +
             "&client_id=" + APPID +
             "&redirect_uri=" + URLEncoder.encode(URL) +
             "&state=" + uuid;

     return PasswordUtils.redirectTo(url);
 }

“新浪微博” 互聯的接口文檔中建議我們在授權登錄時傳入一個加密的數據防止被攻擊,我們傳入了UUID,最後重定向到授權頁面
授權登錄
3、我們在授權頁面,登錄了 “新浪微博” 賬號,並同意授權後,就回到了我們創建應用是設置的回調地址裏面了

/**
  * 授權回調
  */
 @GetMapping(value = "/callback")
 public String qqCallback(HttpServletRequest request) throws Exception {
     HttpSession session = request.getSession();
     // 得到Authorization Code
     String code = request.getParameter("code");
     // 我們放在地址中的狀態碼
     String state = request.getParameter("state");
     String uuid = (String) session.getAttribute("state");

     // 驗證信息我們發送的狀態碼
     if (null != uuid) {
         // 狀態碼不正確,直接返回登錄頁面
         if (!uuid.equals(state)) {
             return PasswordUtils.redirectTo("/login");
         }
     }

     // Step2:通過Authorization Code獲取Access Token
     String url = "https://api.weibo.com/oauth2/access_token?grant_type=authorization_code" +
             "&client_id=" + APPID +
             "&client_secret=" + APPKEY +
             "&code=" + code +
             "&redirect_uri=" + URL;
     JSONObject accessTokenJson = WeiboHttpClient.getAccessToken(url);
     // 拿到用戶的唯一標識--uid
     String uid = accessTokenJson.getString("uid");

     // Step3: 獲取用戶信息
     url = "https://api.weibo.com/2/users/show.json?access_token=" + accessTokenJson.get("access_token") +
             "&uid=" + accessTokenJson.get("uid");
     JSONObject jsonObject = WeiboHttpClient.getUserInfo(url);
     // 根據openid在數據庫中查找是否存在此用戶
     UserInfo userInfo = userInfoService.getUserInfo(uid, Const.UserCategory.USER_CATEGORY_WEIBO);
     // 如果存在此用戶,則檢查該用戶是否合法,返回首頁
     if (null != userInfo) {
         if (2 == userInfo.getStatus()) {
             return PasswordUtils.redirectTo("/login");
         } else {
             session.setAttribute(Const.SYSTEM_USER_SESSION, userInfo);
             // 新增一條登錄日誌
             loginLogService.saveLoginLog(userInfo.getId(), ServletUtils.getServletPojo(request));
         }
     }
     // 該用戶不存在,則需要新建一個用戶保存到數據庫中,並登錄
     else {
         // 隨機生成賬戶
         String loginAccount = Const.Number.NUMBER_ONE + RandomUtils.getCurrentTimeMillis(Const.Number.NUMBER_EIGHT);
         // 隨機生成鹽值
         String salt = PasswordUtils.getSalt();
         // 加密後的密碼,默認密碼123456
         String password = PasswordUtils.getMd5("123456", loginAccount, salt);
         // 性別
         String sexStr = (String) jsonObject.get("gender");
         int sex = Const.Sex.SEX_SECRECY;
         // 男
         if (Const.Sex.SEX_MAN_EN.equals(sexStr)) {
             sex = Const.Sex.SEX_MAN;
         }
         // 女
         else if (Const.Sex.SEX_WOMAN_EN.equals(sexStr)) {
             sex = Const.Sex.SEX_WOMAN;
         }
         // 保存新用戶
         userInfoService.saveUserInfo(loginAccount, jsonObject.getString("name"), jsonObject.getString("description"), password, salt, jsonObject.getString("avatar_hd"), sex, uid, Const.UserCategory.USER_CATEGORY_WEIBO);
         // 根據openid在數據庫中查找是否存在此用戶
         userInfo = userInfoService.getUserInfo(uid, Const.UserCategory.USER_CATEGORY_WEIBO);
         // 將當前用戶保存到session中去
         session.setAttribute(Const.SYSTEM_USER_SESSION, userInfo);
         // 默認加主號爲好友
         friendInfoDao.saveFridendInfo(Const.Number.NUMBER_ONE, userInfo.getId());
         // 新增一條登錄日誌
         loginLogService.saveLoginLog(userInfo.getId(), ServletUtils.getServletPojo(request));
     }
     return PasswordUtils.redirectTo("/success");
 }

以上代碼,從我自己的項目中拷貝而來,如果你直接使用,你需要對其業務代碼進行修改

4、第三步代碼中所用到的網絡接口方法,我放在了 WeiboHttpClient.java 文件中,主要有兩個方法

/**
 * 獲取Access Token
 * post
  */
 public static JSONObject getAccessToken(String url) throws IOException {
     HttpClient client = HttpClients.createDefault();
     HttpPost httpPost = new HttpPost(url);
     HttpResponse response = client.execute(httpPost);
     HttpEntity entity = response.getEntity();
     if (null != entity) {
         String result = EntityUtils.toString(entity, "UTF-8");
         return JSONObject.parseObject(result);
     }
     httpPost.releaseConnection();
     return null;
 }

 /**
 * 獲取微博用戶信息
 * get
  */
 public static JSONObject getUserInfo(String url) throws IOException {
     JSONObject jsonObject = null;
     CloseableHttpClient client = HttpClients.createDefault();

     HttpGet httpGet = new HttpGet(url);
     HttpResponse response = client.execute(httpGet);
     HttpEntity entity = response.getEntity();

     if (entity != null) {
         String result = EntityUtils.toString(entity, "UTF-8");
         jsonObject = JSONObject.parseObject(result);
     }

     httpGet.releaseConnection();

     return jsonObject;
 }

以上,就是完成 “新浪微博” 授權登錄的過程,相比 QQ 授權登錄 少了一個獲取 openID 的步驟,新浪微博 登錄以 uid 作爲唯一標識

  • 五、總結

總結來說如圖所示
新浪微博登錄流程圖
如您在閱讀中發現不足,歡迎留言!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章