【第三方互联】十五、百度(baidu)授权第三方登录

今天继续学习:百度(baidu)授权第三方登录

官网地址:https://developer.baidu.com/

注册账号,登录官网

  • 2、注册成为“百度开发者”
    登录成功
    在页面底部找到“应用管理”,当然,我们还需要申请成为“百度开发者”,填写信息
    开发者信息
    点击提交后,
    成为百度开发者

  • 3、创建应用
    创建过程
    填入应用的名称
    基本信息
    我们点击“安全设置”,填写应用高级信息
    安全设置

  • 4、将应用信息保存到项目中
    配置信息
    由于我使用的是 SpringBoot 项目,我放在了 application.yml 文件中

  • 二、开始开发

  • 1、引入 Maven 依赖

<!-- 网络请求 -->
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
	<version>4.5.6</version>
</dependency>
<!-- alibaba的fastjson -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.51</version>
</dependency>

这里主要用到了网络请求,已经 JSON 转换工具,其余的依赖请自行加入

  • 2、在页面放置 “百度(baidu)” 授权登录的 DOM 元素
<a th:href="@{baidu/auth}" class="link" title="百度登录"><i class="iconfont icon-baidu"></i></a>

这里使用的是阿里的 iconfont 图标

  • 三、创建 “百度(baidu)” 授权登录的 Controller,BaiduController.java

  • 1、从配置文件中获取 “Github” 配置信息

/**
 * 百度授权中提供的 apikey 和 secretkey
 */
@Value("${baidu.oauth.apikey}")
public String APIKEY;
@Value("${baidu.oauth.secretkey}")
public String SECRETKEY;
@Value("${baidu.oauth.callback}")
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 = "http://openapi.baidu.com/oauth/2.0/authorize?response_type=code" +
            "&client_id=" + APIKEY +
            "&redirect_uri=" + URLEncoder.encode(URL) +
            "&state=" + uuid +
            "&scope=basic,super_msg";

    return PasswordUtils.redirectTo(url);
}

注意:scope 参数的值可多选

basic:用户基本权限,可以获取用户的基本信息 。
super_msg:往用户的百度首页上发送消息提醒,相关API任何应用都能使用,但要想将消息提醒在百度首页显示,需要第三方在注册应用时额外填写相关信息。
netdisk:获取用户在个人云存储中存放的数据。

多个值用逗号隔开即可

接口文档中建议我们在授权登录时传入一个加密的数据防止被攻击,我们传入了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://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code" +
            "&code=" + code +
            "&client_id=" + APIKEY +
            "&client_secret=" + SECRETKEY +
            "&redirect_uri=" + URL;
    JSONObject accessTokenJson = BaiduHttpClient.getAccessToken(url);

    // Step3: 获取用户信息
    url = "https://openapi.baidu.com/rest/2.0/passport/users/getInfo?access_token=" + accessTokenJson.get("access_token");
    JSONObject jsonObject = BaiduHttpClient.getUserInfo(url);

    /**
     * TODO 获取到用户信息之后,你自己的业务逻辑
     * 判断数据库是否有次用户,有---登录成功,无---保存用户至数据库,登录成功
     */

    return PasswordUtils.redirectTo("/success");
}
  • 四、上面回调方法中所用到的网络接口方法,我放在了 BaiduHttpClient.java 文件中,主要有两个方法

  • 1、使用 code 获取Access Token

/**
 * 获取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;
}
  • 2、使用 Access Token 获取用户信息
/**
 * 获取用户信息
 * get
 */
public static JSONObject getUserInfo(String url) throws IOException {
    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");
        return JSONObject.parseObject(result);
    }

    httpGet.releaseConnection();
    return null;
}

最终我们获取到一个 JSON 对象,该对象包含了用户的信息,例如:id,username,birthday,sex等等。

返回用户详情信息,详情见 返回用户详细资料API文档

https://developer.baidu.com/wiki/index.php?title=docs/oauth/rest/file_data_apis_list#.E8.BF.94.E5.9B.9E.E7.94.A8.E6.88.B7.E8.AF.A6.E7.BB.86.E8.B5.84.E6.96.99
https://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization
  • 五、总结

该授权认证过程符合 OAuth2 认证基本流程,对于应用而言,其流程由获取Authorization Code和通过Authorization Code获取Access Token这2步组成,如图所示:
OAuth授权认证
如您在阅读中发现不足,欢迎留言!!!

发布了87 篇原创文章 · 获赞 230 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40065776/article/details/105418674