企业开发-⽹页授权及JS-SDK计⼊流程
企业开发之授权登录注意事项:
1.⽹页授权及JS-SDK需要在企业上配置可信域名
2.企业授权登录⾥⾯填写你的可信域名
调⽤流程为:
A) ⽤户访问第三⽅服务,第三⽅服务通过构造OAuth2链接(参数包括当前第三⽅服务的⾝份ID,以及重定向URI),将⽤户引导到认证服务器的授权页
B) ⽤户选择是否同意授权
C) 若⽤户同意授权,则认证服务器将⽤户重向到第⼀步指定的重定向URI,同时附上⼀个授权码。
D) 第三⽅服务收到授权码,带上授权码来源的重定向URI,向认证服务器申请凭证。
E) 认证服务器检查授权码和重定向URI的有效性,通过后颁发AccessToken(调⽤凭证)
OAuth2接⼊流程
使⽤OAuth2前须知
关于⽹页授权的可信域名
REDIRECT_URL中的域名,需要先配置⾄应⽤的“可信域名”,否则跳转时会提⽰“redirect_uri参数错误”。
要求配置的可信域名,必须与访问链接的域名完全⼀致。举个例⼦:
假定重定向访问的链接是:mail.qq:8080/cgi-bin/helloworld:
配置域名是否正确原因
mail.qq:8080 配置域名与访问域名完全⼀致
email.qq 配置域名必须与访问域名完全⼀致
support.mail.qq 配置域名必须与访问域名完全⼀致
*.qq 不⽀持泛域名设置
mail.qq 配置域名必须与访问域名完全⼀致,包括端⼝号
假定配置的可信域名是 mail.qq:汤灿入狱
访问链接是否正确原因
mail.qq/cgi-bin/helloworld 配置域名与访问域名完全⼀致
mail.qq/cgi-bin/redirect 配置域名与访问域名完全⼀致,与协议头/链接路径⽆关
exmail.qq/cgi-bin/helloworld 配置域名必须与访问域名完全⼀致
关于UserID机制
UserId⽤于在⼀个企业内唯⼀标识⼀个⽤户,通过⽹页授权接⼝可以获取到当前⽤户的UserId信息,如果需要获取⽤户的更多信息可以调⽤通讯录管理 - 成员接⼝来获取。
缓存⽅案建议
通过OAuth2.0验证接⼝获取成员⾝份会有⼀定的时间开销。对于频繁获取成员⾝份的场景,建议采⽤如下⽅案:
1、企业应⽤中的URL链接直接填写企业⾃⼰的页⾯地址
2、成员操作跳转到步骤1的企业页⾯时,企业后台校验是否有标识成员⾝份的cookie信息,此cookie由企业⽣成
3、如果没有匹配的cookie,则重定向到OAuth验证链接,获取成员的⾝份信息后,由企业后台植⼊标识成员⾝份的cookie信息
4、根据cookie获取成员⾝份后,再进⼊相应的页⾯
构造⽹页授权链接养猪教程
如果企业需要在打开的⽹页⾥⾯携带⽤户的⾝份信息,第⼀步需要构造如下的链接来获取code参数:
open.weixin.qq/connect/oauth2/authorize?
appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
参数说明:
参数必须说明
appid 是企业的CorpID
redirect_uri 是授权后重定向的回调链接地址,请使⽤urlencode对链接进⾏处理
response_type 是返回类型,此时固定为:code
scope 是
应⽤授权作⽤域。
snsapi_base:静默授权,可获取成员的基础信息;
snsapi_userinfo:静默授权,可获取成员的详细信息,但不包含⼿机、邮箱;
snsapi_privateinfo:⼿动授权,可获取成员的详细信息,包含⼿机、邮箱。
state 否重定向后会带上state参数,企业可以填写a-zA-Z0-9的参数值,长度不可超过128个字节
#wechat_redirect 是终端使⽤此参数判断是否需要带上⾝份信息
agentid 否企业应⽤的id。
当scope是snsapi_userinfo或snsapi_privateinfo时,该参数必填。
注意redirect_uri的域名必须与该应⽤的可信域名⼀致。
员⼯点击后,页⾯将跳转⾄ redirect_uri?code=CODE&state=STATE,企业可根据code参数获得员⼯的userid。code长度最⼤为512字节。
权限说明:
企业⽆限制;第三⽅使⽤snsapi_privateinfo的scope时,应⽤必须有’成员敏感信息授权’的权限。
根据code获取成员信息
请求⽅式:GET(HTTPS)
请求地址:qyapi.weixin.qq/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
参数说明:
参数必须说明
access_token 是调⽤接⼝凭证
code 是通过成员授权获取到的code,最⼤为512字节。每次成员授权带上的code将不⼀样,code只能使⽤⼀次,5分钟未被使⽤⾃动过期。
权限说明:
跳转的域名须完全匹配access_token对应应⽤的可信域名。
返回结果:
a) 当⽤户为企业成员时返回⽰例如下:
创意招聘广告语{
"errcode":0,
"errmsg":"ok",
"UserId":"USERID",
"DeviceId":"DEVICEID",
"user_ticket":"USER_TICKET",
"expires_in":7200
}
参数说明
errcode 返回码
errmsg 对返回码的⽂本描述内容
UserId 成员UserID
DeviceId ⼿机设备号(由企业在安装时随机⽣成,删除重装会改变,升级不受影响)
user_ticket 成员票据,最⼤为512字节。
scope为snsapi_userinfo或snsapi_privateinfo,且⽤户在应⽤可见范围之内时返回此参数。
后续利⽤该参数可以获取⽤户信息或敏感信息。
expires_in user_token的有效时间(秒),随user_ticket⼀起返回
液晶显示器黑屏
⾮企业成员授权时返回⽰例如下:
{
"errcode":0,
"errmsg":"ok",
"OpenId":"OPENID",
"DeviceId":"DEVICEID"
}
参数说明
errcode 返回码
errmsg 对返回码的⽂本描述内容
OpenId ⾮企业成员的标识,对当前企业唯⼀
DeviceId ⼿机设备号(由企业在安装时随机⽣成,删除重装会改变,升级不受影响)
出错返回⽰例:
{
"errcode":40029,
"errmsg":"invalid code"
}
实现代码:
package com.eqiao.ller;
import com.eqiao.bidata.weixinmon.AccessToken;
import com.eqiao.bidata.weixinmon.Result;
import com.eqiao.bidata.weixinmon.WeiXinQiYeConstants;
import com.eqiao.bidata.weixinmon.WeiXinQiYeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
/**
* 单纯实现OAuth2验证,不使⽤注解及
* Created by zhaoxinguo on 2017/7/11.
*/
@Controller
public class SimpleOAuth2Controller {
private Logger logger = Logger(SimpleOAuth2Controller.class);
/**
* 拼接⽹页授权链接
* 此处步骤也可以⽤页⾯链接代替
* @return空调滴水
*/
@RequestMapping(value = { "/oauth2wx.do" })
public String Oauth2API(HttpServletRequest request){
//获取项⽬域名
String requestUrl = ServerName();
String contextPath = ContextPath();
logger.info("domain name: " + requestUrl + " project name: " + contextPath);
//拼接回调地址
String backUrl ="" + requestUrl + contextPath + "/oauth2me.do";
String redirect_uri = "";
try {
redirect_uri = de(backUrl, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
<("ecdoe error: " + e.getMessage());
}
String oauth2Url = "open.weixin.qq/connect/oauth2/authorize?appid=" + WeiXinQiYeConstants.CORPID + "&redirect_uri=" + redirect_uri
+ "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
return "redirect:" + oauth2Url;
}
/**
* 授权回调请求处理
* @return
*/
@RequestMapping(value = { "/oauth2me.do" })
public String oAuth2Url(HttpServletRequest request, @RequestParam String code){
// 调⽤获取access_token的接⼝
AccessToken accessToken = WeiXinQiYeUtil.access_token();
HttpSession session = Session();
if (accessToken != null && Access_token() != null) {
// 调⽤获取⽤户信息的接⼝
String UserId = Access_token(), code, WeiXinQiYeConstants.AGENTID);
logger.info("UserId: " + UserId);
if (UserId != null) {
session.setAttribute("UserId", UserId);
logger.info("UserId放⼊session成功!");
}
}
// 这⾥简单处理,存储到session中
return "user/result";
}
/**
* 调⽤接⼝获取⽤户信息
*
* @param token
* @param code
* @return
*/
public String getMemberGuidByCode(String token, String code, String agentId) {
logger.info("code==" + code + " token=" + token + " agentId=" +agentId);
Result result = WeiXinQiYeUtil.oAuth2GetUserByCode(token, code, agentId);
logger.info("result= " + result);
if (Errcode().equals("0")) {
if (UserId() != null && UserId().length() > 0) {
// 此处可以通过授权⽤code还钱的Userid查询⾃⼰本地服务器中的数据
logger.info("UserId(): " + UserId());
UserId();
}
}
return "";
}
}
/**
重剑比赛规则* OAuth2验证接⼝根据code获取成员信息
*
* @param token
* @param code
* @return
*/
public static Result oAuth2GetUserByCode(String token, String code, String agentId) {
Result result = new Result();
String menuUrl = WeiXinQiYeConstants.GET_place("ACCESS_TOKEN", token).replace("CODE", code).replace("AGENTID", agentId + "");
String userinfo = JHttpUtils.doGet(menuUrl);
logger.info("userinfo: " + userinfo);
JSONObject jsonObject = null;
if (userinfo != null) {
try {
jsonObject = JSONObject.fromObject(userinfo);
logger.info("jsonObject: " + jsonObject);
if (String("UserId") != null && String("UserId").length() > 0) {
result.String("errmsg"));
result.String("errcode"));
result.String("UserId"));
} else {
result.String("errmsg"));
result.String("errcode"));
}
} catch (Exception e) {
result.setErrmsg("accessToken 超时......");
result.setErrcode("42001");
}
}
return result;
}
⼀个完整的流程就是这样。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论