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)
为了实现上述效果,应该为“微博登录”按钮图片添加如下前台代码:
// 微博登录 // 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.2 后端代码(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 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 getToken(String code) throws Exception {
Map weiBoProperties = new HashMap();
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();
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;
}
5 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 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;
}
6 个人网站(YOUYOUSHOP),QQ,微博已经实现,需要的小伙伴可以测试
6.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
应用权限不足
6.2 每个人做的项目需求不同,可能会出现不同的问题,文章可以参考,也可以留言你的问题,我会帮你解决,大家一起加油