企业微信授权登录(Oauth2.0)
OAuth2简介
OAuth2的设计背景,在于允许用户在不告知第三方自己的帐号密码情况下,通过授权方式,让第三方服务可以获取自己的资源信息。
下面简单说明OAuth2中最经典的Authorization Code模式,流程如下:
程图中,包含四个角色。
- ResourceOwner为资源所有者,即为用户
- User-Agent为浏览器
- AuthorizationServer为认证服务器,可以理解为用户资源托管方,比如企业微信服务端
- Client为第三方服务
调用流程为:
A) 用户访问第三方服务,第三方服务通过构造OAuth2链接(参数包括当前第三方服务的身份ID,以及重定向URI),将用户引导到认证服务器的授权页
B) 用户选择是否同意授权
C) 若用户同意授权,则认证服务器将用户重定向到第一步指定的重定向URI,同时附上一个授权码。
D) 第三方服务收到授权码,带上授权码来源的重定向URI,向认证服务器申请凭证。
E) 认证服务器检查授权码和重定向URI的有效性,通过后颁发AccessToken(调用凭证)
实际使用OAuth流程
我们日常中使用的登录大多以账号密码登录为主,在企业pass服务盛行的今天,我们也会把一些业务系统或者一些人事系统集成到企业微信或者钉钉上。恰好遇到一个关于业务系统集成企业微信的需求,企业微信是支持Oauth2.0。不多BB,直接上图
企业微信OAuth2接入流程
自己开发的实际流程
- 在企业微信后台配置跳转的页面。
- 页面向自己的服务器后台发送http请求并且携带参数code。
- 自己的微信后台去和企业微信服务器后台进行交互,拿到用户的信息。
- 和自己的网关服务进行交互,拿到自己服务器的token,返回给前端。
代码开发
实际的代码流程十分简单,注意企业微信的token是需要缓存在服务器的,这里贴一个自己写的获取access_token并且缓存起来的代码,也算是上述这些流程里边稍微思考的. 省去了一些注释,防止暴露其他信息,代码思路可以参考。
private static volatile AccessToken accessToken;
public AccessToken getAccessToken() {
if (accessToken == null){
AccessToken token = freshAccessToken();
if (token != null){
accessToken = token;
}
}else {
//计算上次记录的获取的时间
long diffTime =(new Date().getTime())-(accessToken.getSatrtTime().getTime())+ 120;
if(diffTime>=accessToken.getExpires_in()){//如果时间差加上提前的时间值大于等于了微信规定的有效期限则需要重新向微信服务器刷新最新accessToken值
AccessToken toke = freshAccessToken();
if(toke!=null){
accessToken = toke;
}
}
}
return accessToken;
}
/**
* 请求企业微信后台服务 获取access_token
* @return
*/
private synchronized AccessToken freshAccessToken() throws BaseException{
String tokenBody = HttpUtil.get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="+ QWeChatConstant.COPE_ID+"&corpsecret="+QWeChatConstant.COPE_SECRET);
JSONObject jsonObject = JSON.parseObject(tokenBody);
AccessToken accessToken = null;
if (jsonObject.getIntValue("errcode")==0){
String accessTokenString = jsonObject.getString("access_token");
String expiresIn = jsonObject.getString("expires_in");
Timestamp startTime = new Timestamp(new Date().getTime());
accessToken = new AccessToken(accessTokenString, Long.parseLong(expiresIn), startTime);
}
return accessToken;
}
}