zoukankan      html  css  js  c++  java
  • SpringBoot+Vue实现第三方微博登录(二)

    1 准备工作

    本步骤的作用

      接入微博登录前,网站需首先进行申请,获得对应的appid与appkey,以保证后续流程中可正确对网站与用户进行验证与授权。

    1.1 保存appid和appkey

      appid:应用的唯一标识。在OAuth2.0认证过程中,appid的值即为oauth_consumer_key的值。

      appkey:appid对应的密钥,访问用户资源时用来验证应用的合法性。在OAuth2.0认证过程中,appkey的值即为oauth_consumer_secret的值。

    2 放置“微博登录”按钮

    本步骤的作用

      在网站页面上放置“微博登录”按钮,并为按钮添加前台代码,实现点击按钮即弹出微博登录对话框 。

    2.1 请求用户授权Token,Oauth2/authorize

    请求地址

      PC网站:https://api.weibo.com/oauth2/authorize

    请求方法

      GET/POST

    请求参数

     必选类型及范围说明
    client_id true string 申请应用时分配的AppKey。
    redirect_uri true string 授权回调地址,站外应用需与设置的回调地址一致,站内应用需填写canvas page的地址。
    scope false string 申请scope权限所需参数,可一次申请多个scope权限,用逗号分隔。使用文档
    state false string 用于保持请求和回调的状态,在回调时,会在Query Parameter中回传该参数。开发者可以用这个参数验证请求有效性,也可以记录用户请求授权页前的位置。这个参数可用于防止跨站请求伪造(CSRF)攻击
    display false string 授权页面的终端类型,取值见下面的说明。
    forcelogin false boolean 是否强制用户重新登录,true:是,false:否。默认false。
    language false string 授权页语言,缺省为中文简体版,en为英文版。英文版测试中,开发者任何意见可反馈至 @微博API

    返回数据:

    返回值字段字段类型字段说明
    code string 用于第二步调用oauth2/access_token接口,获取授权后的access token。
    state string 如果传递参数,会回传该参数。

    返回示例:

      // 请求地址
      https://api.weibo.com/oauth2/authorize?client_id=123050457758183&redirect_uri=http://www.example.com/response&response_type=code
    
      // 同意授权后会重定向
      http://www.example.com/response&code=CODE

    2.2 下载“微博登录”按钮图片,并将按钮放置在页面合适的位置

      可以到阿里矢量图库下载更多图标:阿里巴巴矢量图标库 。

    2.3 为“微博登录”按钮添加前台代码

    2.3.1 效果演示

    2.3.2 前端代码(Vue)

      为了实现上述效果,应该为“微博登录”按钮图片添加如下前台代码:

    <div style="line-height: 22px;margin:0 0 8px 0;color: #9b9b9b;">
    <span style="vertical-align:middle">第三方登录:</span>
    <img :src="qqIcon" width="22" height="22" style="vertical-align:middle;margin-left: 2px" title="QQ">
    <img :src="baiduIcon" width="22" height="22" style="vertical-align:middle;margin-left: 2px" title="百度">
    <img :src="weiboIcon" width="22" height="22" style="vertical-align:middle;margin-left: 2px" title="微博">
    <img :src="zhifubaoIcon" width="22" height="22" style="vertical-align:middle;margin-left: 2px" title="支付宝">
    <img :src="giteeIcon" width="22" height="22" style="vertical-align:middle;margin-left: 2px" title="Gitee">
    <img :src="githubIcon" width="22" height="22" style="vertical-align:middle;margin-left: 2px" title="GitHub">
    </div>

     

    // 微博登录
    // https://api.weibo.com/oauth2/authorize?client_id=203394&response_type=code&redirect_uri=https%3A%2F%2Fwww.lovezmy.link%2FweiBoCallback&state=439b3e51799553ab
    handleWeiBoLogin() {
    getWeiBoCode().then(res => {
    window.location.href = res;
    })
    },

    2.3.3 后端代码(Java)

      微博登录配置文件信息:

    # 微博登录配置
    weibo.appID = 266666664(替换成你的)
    weibo.appKEY = 666666666613a0b31579(替换成你的)
    weibo.redirectURI = https://www.lovezmy.link/weiBoCallback(替换成你的)
    weibo.authorizeURL = https://api.weibo.com/oauth2/authorize
    weibo.accessToken = https://api.weibo.com/oauth2/access_token
    weibo.userJson = https://api.weibo.com/2/users/show.json
    weibo.revokeoauth = https://api.weibo.com/oauth2/revokeoauth2

      读取配置文件信息常量类:

    package com.modules.security.constants;

    import lombok.Data;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;

    /**
    * 微博登陆常量配置类
    */

    @Data
    @Configuration
    @PropertySource("classpath:thirdparty/config.properties") // 指定配置文件的路径,属性文件需放在根目录的resources文件夹下面,才能被读取出来
    public class WeiBoConstants {

    @Value("${weibo.appID}")
    private String appID;

    @Value("${weibo.appKEY}")
    private String appKEY;

    @Value("${weibo.redirectURI}")
    private String redirectURI;

    @Value("${weibo.authorizeURL}")
    private String authorizeURL;

    @Value("${weibo.accessToken}")
    private String accessToken;

    @Value("${weibo.userJson}")
    private String userJson;

    @Value("${weibo.revokeoauth}")
    private String revokeoauth;

    }

      Conteoller(获取微博登录的url)

       /**
         * 获得跳转到微博登录页的url,前台直接a连接访问
         *
         * @return
         * @throws Exception
         */
        @LogAnnotation("获得跳转到微博登录页的url")
        @ApiOperation("获得跳转到微博登录页的url")
        @AnonymousAccess
        @GetMapping("/getWeiBoCode")
        public ResponseEntity<Object> getWeiBoCode() throws Exception {
            // 授权地址 ,进行Encode转码
            String authorizeURL = weiBoConstants.getAuthorizeURL();
    
            // 回调地址 ,回调地址要进行Encode转码
            String redirectUri = weiBoConstants.getRedirectURI();
    
            //用于第三方应用防止CSRF攻击
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            // 保存到Redis
            redisUtils.set(WEIBOSTATE + "-" + uuid, uuid, expiration, TimeUnit.MINUTES);
    
            // 拼接url
            StringBuilder url = new StringBuilder();
            url.append(authorizeURL);
            url.append("?client_id=" + weiBoConstants.getAppID());
            url.append("&response_type=code");
            // 转码
            url.append("&redirect_uri=" + URLEncodeUtil.getURLEncoderString(redirectUri));
            url.append("&state=" + uuid);
    
            return ResponseEntity.ok(url);
        }

    3 获取授权过的Access Token

    本步骤的作用

      通过用户验证登录和授权,获取Access Token,为下一步获取用户的uid做准备。

      同时,Access Token是应用在调用OpenAPI访问和修改用户数据时必须传入的参数。

    3.1 简介

      即server-side模式,是OAuth2.0认证的一种模式,又称Web Server Flow。

      适用于需要从web server访问的应用,例如Web网站。

    3.2 获取Authorization Code

    请求地址

      PC网站:https://api.weibo.com/oauth2/authorize

    请求方法

      GET/POST

    请求参数

     必选类型及范围说明
    client_id true string 申请应用时分配的AppKey。
    redirect_uri true string 授权回调地址,站外应用需与设置的回调地址一致,站内应用需填写canvas page的地址。
    scope false string 申请scope权限所需参数,可一次申请多个scope权限,用逗号分隔。使用文档
    state false string 用于保持请求和回调的状态,在回调时,会在Query Parameter中回传该参数。开发者可以用这个参数验证请求有效性,也可以记录用户请求授权页前的位置。这个参数可用于防止跨站请求伪造(CSRF)攻击
    display false string 授权页面的终端类型,取值见下面的说明。
    forcelogin false boolean 是否强制用户重新登录,true:是,false:否。默认false。
    language false string 授权页语言,缺省为中文简体版,en为英文版。英文版测试中,开发者任何意见可反馈至 @微博API

    返回说明

    1. 如果用户成功登录并授权,则会跳转到指定的回调地址,并在redirect_uri地址后带上Authorization Code和原始的state值。如:

      https://api.weibo.com/oauth2/authorize?code=1E83738E79B0CEBF13FC7C3B094D9B3C&state=cca3c15c527649409cccd889ad2963fe

    2. 如果用户在登录授权过程中取消登录流程,对于PC网站,登录页面直接关闭。

    3.3 通过Authorization Code获取Access Token

    请求地址

      PC网站:https://api.weibo.com/oauth2/authorize

    请求方法

      POST

    请求参数

     必选类型及范围说明
    client_id true string 申请应用时分配的AppKey。
    client_secret true string 申请应用时分配的AppSecret。
    grant_type true string 请求的类型,填写authorization_code
    code ture string 调用authorize获得的code值。
    rediect_url ture string 回调地址,需需与注册应用里的回调地址一致。

    返回说明

    返回值字段字段类型字段说明
    access_token string 用户授权的唯一票据,用于调用微博的开放接口,同时也是第三方应用验证微博用户登录的唯一票据,第三方应用应该用该票据和自己应用内的用户建立唯一影射关系,来识别登录状态,不能使用本返回值里的UID字段来做登录识别。
    expires_in string access_token的生命周期,单位是秒数。
    remind_in string access_token的生命周期(该参数即将废弃,开发者请使用expires_in)。
    uid string 授权用户的UID,本字段只是为了方便开发者,减少一次user/show接口调用而返回的,第三方应用不能用此字段作为用户登录状态的识别,只有access_token才是用户授权的唯一票据。
    {
      "access_token":"2.00kAsM_435345353349baFTDB",
    "remind_in":"157679999", "expires_in":157679999, "uid":"6342222336", "isRealName":"true"
    }

    接口代码:

       /**
         * 获得token信息(授权,每个用户的都不一致) --> 获得token信息该步骤返回的token期限为一个月
         *
         * @return
         * @throws Exception
         */
        public Map<String, Object> getToken(String code) throws Exception {
            Map<String, Object> weiBoProperties = new HashMap<String, Object>();
            try {
                //  https://api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID
                //  &client_secret=YOUR_CLIENT_SECRET
                //  &grant_type=authorization_code
                //  &redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE
                StringBuilder url = new StringBuilder();
                url.append(weiBoConstants.getAccessToken());
                url.append("?client_id=" + weiBoConstants.getAppID());
                url.append("&client_secret=" + weiBoConstants.getAppKEY());
                url.append("&grant_type=authorization_code");
                // 回调地址
                String redirectUri = weiBoConstants.getRedirectURI();
                // 转码
                url.append("&redirect_uri=" + URLEncodeUtil.getURLEncoderString(redirectUri));
                url.append("&code=" + code);
    
                // 获得token
                String result = HttpUtil.post(url.toString(), "UTF-8");// 把token保存
                JSONObject object = JSONObject.fromObject(result);
                //token信息
                weiBoProperties = new HashMap<String, Object>();
                weiBoProperties.put("accessToken", object.getString("access_token"));
                weiBoProperties.put("remindIn", object.getString("remind_in"));
                weiBoProperties.put("expiresIn", object.getString("expires_in"));
                weiBoProperties.put("uid", object.getString("uid"));
            } catch (Exception e) {
                throw new BadRequestException("微博登录信息异常,请重试!!!");
            }
            return weiBoProperties;
        }

    4 OpenAPI调用说明_OAuth2.0

    本步骤的作用

      获取到Access Token和uid后,可通过调用OpenAPI来获取或修改用户个人信息。

    请求地址

      PC网站:https://api.weibo.com/2/users/show.json

    请求方法

      GET

    请求参数

     必选类型及范围说明
    access_token true string 采用OAuth授权方式为必填参数,OAuth授权后获得。
    uid true int64 需要查询的用户ID。

    返回说明:

    package com.modules.security.entity;
    
    import lombok.Data;
    import java.io.Serializable;
    
    /**
     * 微博登录用户信息
     *
     * @author Liyh
     * @date 2020/12/22
     */
    
    @Data
    public class WeiBoUserInfo implements Serializable {
        private String idstr;                    // 字符串型的用户UID
        private String screen_name;              // 用户昵称
        private String name;                     // 友好显示名称
        private String province;                 // 用户所在省级ID
        private String city;                     // 用户所在城市ID
        private String location;                 // 用户所在地
        private String description;              // 用户个人描述
        private String url;                      // 用户博客地址
        private String profile_image_url;        // 用户头像地址(中图),50×50像素
        private String profile_url;              // 用户的微博统一URL地址
        private String domain;                   // 用户的个性化域名
        private String weihao;                   // 用户的微号
        private String gender;                   // 性别,m:男、f:女、n:未知
        private String followers_count;          // 粉丝数
        private String friends_count;            // 关注数
        private String statuses_count;           // 微博数
        private String favourites_count;         // 收藏数
        private String created_at;               // 用户创建(注册)时间
        private String following;                // 暂未支持
        private String allow_all_act_msg;        // 是否允许所有人给我发私信,true:是,false:否
        private String geo_enabled;              // 是否允许标识用户的地理位置,true:是,false:否
        private String verified;                 // 是否是微博认证用户,即加V用户,true:是,false:否
        private String verified_type;            // 是否是微博认证用户,即加V用户,true:是,false:否
        private String remark;                   // 用户备注信息,只有在查询用户关系时才返回此字段
        private String allow_all_comment;        // 是否允许所有人对我的微博进行评论,true:是,false:否
        private String avatar_large;             // 用户头像地址(大图),180×180像素
        private String avatar_hd;                // 用户头像地址(高清),高清头像原图
        private String verified_reason;          // 认证原因
        private String follow_me;                // 该用户是否关注当前登录用户,true:是,false:否
        private String online_status;            // 用户的在线状态,0:不在线、1:在线
        private String bi_followers_count;       // 用户的互粉数
        private String lang;                     // 用户当前的语言版本,zh-cn:简体中文,zh-tw:繁体中文,en:英语
    }

    接口代码:

       /**
         * accessToken,uid 获取用户信息
         */
        public String getUserJson(Map<String, Object> weiBoProperties) throws Exception {
            String result = null;
            try {
                // 取出token
                String accessToken = (String) weiBoProperties.get("accessToken");
                String uid = (String) weiBoProperties.get("uid");
                if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(uid)) {
                    throw new BadRequestException("微博登录信息异常,请重试!!!");
                }
                // 拼接url
                StringBuilder url = new StringBuilder();
                url.append(weiBoConstants.getUserJson());
                url.append("?access_token=" + accessToken);
                url.append("&uid=" + uid);
    
                // 获取微博用户信息相关数据
                result = HttpClientUtils.get(url.toString(), "UTF-8");
            } catch (Exception e) {
                throw new BadRequestException("微博登录信息异常,请重试!!!");
            }
            return result;
        }

    5 个人网站(YOUYOUSHOP),需要的小伙伴可以测试 

    5.1 OAuth2.0错误响应中的错误码定义如下表所示:

    错误码(error)错误编号(error_code)错误描述(error_description)
    redirect_uri_mismatch 21322 重定向地址不匹配
    invalid_request 21323 请求不合法
    invalid_client 21324 client_id或client_secret参数无效
    invalid_grant 21325 提供的Access Grant是无效的、过期的或已撤销的
    unauthorized_client 21326 客户端没有权限
    expired_token 21327 token过期
    unsupported_grant_type 21328 不支持的 GrantType
    unsupported_response_type 21329 不支持的 ResponseType
    access_denied 21330 用户或授权服务器拒绝授予数据访问权限
    temporarily_unavailable 21331 服务暂时无法访问
    appkey permission denied 21337 应用权限不足

    5.2 每个人做的项目需求不同,可能会出现不同的问题,文章可以参考,也可以留言你的问题,我会帮你解决,大家一起加油

  • 相关阅读:
    Linux常用命令大全
    Shell常用命令整理
    登录织梦后台提示用户名不存在的解决方法介绍
    dedecms系统后台登陆提示用户名密码不存在
    dede被注入后台提示用户名不存在解决方法
    织梦dedecmsV5.7联动类型无法显示的处理方法
    漏洞安全防范
    Sublime 安装、插件CoolFormat
    如何查看sublime安装了哪些插件
    本地如何使用phpstudy环境搭建多站点
  • 原文地址:https://www.cnblogs.com/liyhbk/p/15251484.html
Copyright © 2011-2022 走看看