一.本篇文章要點
1.1 .首先看一下企業微信的官方文檔 :http://work.weixin.qq.com/api/doc#10028 ,官方文檔講的比較簡潔,下面就是我基於這個開發的一個功能!
網頁授權登錄的流程原理圖
1、首先在請求用戶網頁授權之前,開發者需要先到企業微信管理後臺創建一個應用,其次配置授權回調域名。
請注意,這裏填寫的是域名,因此請勿加http://等協議頭;
接下來講下幾個概念,首先是關於網頁授權的倆種scope的區別說明:
1、以snsapi_base爲scope發起的網頁授權,是用來獲取進入頁面的用戶的openid的,並且是靜默授權並自動跳轉到回調頁的。用戶感知的就是直接進入了回調頁(往往是業務頁面)
2、以snsapi_userinfo爲scope發起的網頁授權,是用來獲取用戶的基本信息的。但這種授權需要用戶手動同意,並且由於用戶同意過,所以無須關注,就可在授權後獲取該用戶的基本信息。
其次是accessToken的區別:關於網頁授權access_token和普通access_token的區別
1、微信網頁授權是通過OAuth2.0機制實現的,在用戶授權給公衆號後,公衆號可以獲取到一個網頁授權特有的接口調用憑證(網頁授權access_token),通過網頁授權access_token可以進行授權後接口調用,如獲取用戶基本信息;2、其他微信接口,需要通過基礎支持中的“獲取access_token”接口來獲取到的普通access_token調用。
1.2 移動端網頁授權流程
(1)用戶點擊1.2中菜單按鈕,跳轉至授權頁面
(2)用戶授權成功,頁面重定向到 redirect_uri?code=CODE&state=STATE 頁面
(3)接收code,根據code獲取成員信息(UserId,user_ticket)
(4)拿到UserId後可選擇去根據UserId獲取成員詳細信息, 參見Java企業微信開發_02_通訊錄同步 中的 Contacts_UserService類
(5) 拿到 user_ticket後可選擇去使用user_ticket獲取成員詳情(其中包括用戶頭像)
二.代碼的實現
1.接下來就可以在企業微信後臺創建應用:(如下圖),最重要的就是配置工作臺主頁的那個地址
a.要替換的值:appid(在企業微信後臺--->我的應用-->CorpID就是)
redirect_uri :爲回調地址,(即爲用戶授權登錄後跳轉的接口)
其他參數都爲要替換的,各位小夥伴們參考官方文檔。
工作臺應用主頁中的地址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的appid&redirect_uri=http%3a%2f%2f%2fMTAuthorization&response_type=code&scope=snsapi_privateinfo&agentid=1000048&state=hec#wechat_redirect
2.接下來就是我的接口, WeixinController
@RequestMapping(value = "/MTAuthorization")
public String mTAuthorization(HttpServletRequest request,HttpSession session) {
String code= request.getParameter("code");
String state=request.getParameter("state");
MTAuthorizationService mts=new MTAuthorizationService();
String accessToken=WeiXinUtil.getAccessToken(QiWeiXinParamesUtil.corpId, QiWeiXinParamesUtil.agentSecret,"app").getToken();
//獲取成員信息
JSONObject userInfo=mts.getUserInfo(accessToken, code);
return "redirect:pcmt";
}
3.MTAuthorizationService中:
import com.bos.data.model.BosUserModel;
import com.bos.data.model.UserTicket;
import com.bos.util.WeiXinUtil;
import com.google.gson.Gson;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*
*
*
*/
public class MTAuthorizationService {
private static Logger log = LoggerFactory.getLogger(MenuService.class);
public static final String GET_USERINFO_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";
public static final String GET_USERDETAIL_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=ACCESS_TOKEN";
/** 1.根據code獲取成員信息
* @desc :GET請求、
* 成員信息包括
* UserId 成員UserID
* DeviceId 手機設備號(由企業微信在安裝時隨機生成,刪除重裝會改變,升級不受影響)
* user_ticket 成員票據,最大爲512字節。scope爲snsapi_userinfo或snsapi_privateinfo,且用戶在應用可見範圍之內時返回此參數。
* 後續利用該參數可以獲取用戶信息或敏感信息。
* expires_in user_token的有效時間(秒),隨user_ticket一起返回
*
* @param accessToken
* @param code void
*/
public JSONObject getUserInfo(String accessToken,String code) {
//1.獲取請求的url
String get_userInfo_url=GET_USERINFO_URL.replace("ACCESS_TOKEN", accessToken)
.replace("CODE", code);
//2.調用接口,發送請求,獲取成員信息
JSONObject jsonObject = WeiXinUtil.httpRequest(get_userInfo_url, "GET", null);
System.out.println("jsonObject:"+jsonObject.toString());
//3.錯誤消息處理
if (null != jsonObject) {
if (0 != jsonObject.getInt("errcode")) {
log.error("獲取成員信息失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return jsonObject;
}
/** 2.使用userTicket獲取成員詳情
* @desc :POST請求
*
* @param accessToken
* @param userTicket
* @return JSONObject
*/
public JSONObject getUserDetail(String accessToken,UserTicket userTicket) {
//1.獲取請求地址
String get_userDetail_url=GET_USERDETAIL_URL.replace("ACCESS_TOKEN", accessToken);
//2.準備好請求包體
Gson gson = new Gson();
String jsonUserTicket =gson.toJson(userTicket); //使用gson.toJson(user)即可將user對象順序轉成json
System.out.println("jsonUserTicket:"+jsonUserTicket);
//2.調用接口,發送請求,獲取成員信息
JSONObject jsonObject = WeiXinUtil.httpRequest(get_userDetail_url, "POST", jsonUserTicket);
System.out.println("jsonObject:"+jsonObject.toString());
String userid=jsonObject.get("userid").toString();
System.out.println("userid-------"+userid);
//根據userid獲取整個user對象
//3.錯誤消息處理
if (null != jsonObject) {
if (0 != jsonObject.getInt("errcode")) {
log.error("獲取成員信息失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return jsonObject;
}
}
4.UserTicket
/**
*
*/
package com.bos.data.model;
/**@desc :
*
*
*
*/
public class UserTicket {
private String user_ticket;
/**
* @return the user_ticket
*/
public String getUser_ticket() {
return user_ticket;
}
/**
* @param user_ticket the user_ticket to set
*/
public void setUser_ticket(String user_ticket) {
this.user_ticket = user_ticket;
}
}
5.WeixinUtil
/**
* 135 * 3.獲取access_token 136 * 137 * @param appid 憑證 138 * @param appsecret
* 密鑰 139 * @return 140
*/
public static AccessTokenModel getAccessToken(String appid, String appsecret, String type) {
AccessTokenModel accessToken = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String saveDate = sdf.format(new Date());
String requestUrl = access_token_url.replace("{corpId}", appid)
.replace("{corpsecret}", appsecret);
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
// 如果請求成功
if (null != jsonObject) {
try {
accessToken = new AccessTokenModel();
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
accessToken.setType(type);
accessToken.setSaveDate(saveDate);
} catch (Exception e) {
accessToken = null;
// 獲取token失敗
log.error("獲取token失敗 errcode:{} errmsg:{}",
jsonObject.getInt("errcode"),
jsonObject.getString("errmsg"));
}
}
return accessToken;
}
1.3. 這是企業微信電腦端的界面
第一次進項目直接談這個框,後面點擊項目無需手動確認登陸。
項目中用到了一些類我已列出來了,第一次做這個功能,也參考了網上的一些文章,做的不完善的地方還請多多包含。