企業應用中的URL鏈接(包含自己定義菜單或者消息中的鏈接)。能夠通過OAuth2.0來獲取員工的身份信息。
注意。此URL的域名,必須全然匹配企業應用設置項中的'可信域名'。否則獲取用戶信息時會返回50001錯誤碼。
可信域名設置不包括"http://",僅僅需域名或IP就可以。
OAuth2驗證能夠使用多種方式,此處使用注解方式。設計思路是在須要獲取用戶信息的GET請求上加入注解。然后在調用的時候推斷是否包括此注解,然后做處理流程。
每次請求包括2種情況:
1.不須要獲取用戶信息,直接跳轉到指定視圖;
2.須要獲取用戶信息,此處分2種情況:
a.session中存儲了之前獲取的用戶信息,則直接跳轉到指定視圖。
b.session中不包括用戶信息。則須要構造帶回調參數的URL去微信APIserver獲取code參數,然后通過code參數調用API換取Userid並保存到session。然后再次跳轉到初始請求的視圖頁面。
詳細處理流程例如以下圖:

此處源代碼包含:微信企業號的接入及消息的簡單處理,在此基礎上加入OAuth2的驗證實例。
源代碼下載地址:http://download.csdn.net/detail/rzg813/8015527
詳細實現代碼:
創建攔截器:OAuth2Interceptor
package org.oms.qiye.interceptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class OAuth2Interceptor implements HandlerInterceptor {
/**
* 在DispatcherServlet全然處理完請求后被調用
* 當有攔截器拋出異常時,會從當前攔截器往回運行全部的攔截器的afterCompletion()
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("**運行順序: 3、afterCompletion**");
}
/**
* 在業務處理器處理請求運行完畢后,生成視圖之前運行的動作
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView modelAndView) throws Exception {
System.out.println("**運行順序: 2、postHandle**");
}
/**
* 在業務處理器處理請求之前被調用 假設返回false 從當前的攔截器往回運行全部攔截器的afterCompletion(),再退出攔截器鏈
* 假設返回true 運行下一個攔截器,直到全部的攔截器都運行完畢 再運行被攔截的Controller 然后進入攔截器鏈,
* 從最后一個攔截器往回運行全部的postHandle() 接着再從最后一個攔截器往回運行全部的afterCompletion()
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("**運行順序: 1、preHandle**");
String url = request.getRequestURL().toString();
HttpSession session = request.getSession();
// 先推斷是否有注解
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
OAuthRequired annotation = method.getAnnotation(OAuthRequired.class);
if (annotation != null) {
System.out.println("OAuthRequired:你的訪問須要獲取登錄信息!");
Object objUid = session.getAttribute("UserId");
if (objUid == null) {
String resultUrl = request.getRequestURL().toString();
String param=request.getQueryString();
if(param!=null){
resultUrl+= "?
" + param;
}
System.out.println("resultUrl="+resultUrl);
try {
resultUrl = java.net.URLEncoder.encode(resultUrl, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//請求的路徑
String contextPath=request.getContextPath();
response.sendRedirect(contextPath + "/oauth2.do?resultUrl=" + resultUrl);
return false;
}
}
return true;
}
}
驗證OAuth2注解OAuthRequired
package org.oms.qiye.interceptor;
import java.lang.annotation.*;
/**
* 驗證OAuth2注解
* @author Sunlight
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OAuthRequired {
}
常量類。此處能夠替換為持久化數據讀取。
package org.oms.qiye.util;
public class Constants {
/**
* 常量說明:
* 此處定義的常量須要持久化,能夠保存在數據庫中,在須要的地方讀取。
* 在多企業號中。最好以每一個應用來定義。
*/
public static final int AGENTID = 1;
public static final String TOKEN = "sunlight";
public static final String CORPID = "你的企業號ID";
public static final String Secret = "你的企業號_ACCESS_TOKEN";
public static final String encodingAESKey = "s8vFF4f6AWay3uAdJh79WD6imaam4BV6Kl4eL4UzgfM";
}
OAuth2 處理控制器OAuth2Controller
package org.oms.qiye.web;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.oms.qiye.pojo.AccessToken;
import org.oms.qiye.util.Constants;
import org.oms.qiye.util.QiYeUtil;
import org.oms.qiye.util.Result;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* OAuth2 處理控制器
* @author Sunlight
*
*/
@Controller
public class OAuth2Controller {
/**
* 構造參數並將請求重定向到微信API獲取登錄信息
*
* @param index
* @return
*/
@RequestMapping(value = { "/oauth2.do", "/oauth2" })
public String Oauth2API(HttpServletRequest request, @RequestParam String resultUrl) {
// 此處能夠加入獲取持久化的數據,如企業號id等相關信息
String CropId = Constants.CORPID;
String redirectUrl = "";
if (resultUrl != null) {
String reqUrl =request.getLocalAddr();
String backUrl ="http://" + reqUrl + "/oauth2url.do?oauth2url=" + resultUrl;
System.out.println("backUrl="+backUrl);
redirectUrl = oAuth2Url(CropId, backUrl);
}
return "redirect:" + redirectUrl;
}
/**
* 依據code獲取Userid后跳轉到須要帶用戶信息的終於頁面
*
* @param request
* @param code
* 獲取微信重定向到自己設置的URL中code參數
* @param oauth2url
* 跳轉到終於頁面的地址
* @return
*/
@RequestMapping(value = { "/oauth2url.do" })
public String Oauth2MeUrl(HttpServletRequest request, @RequestParam String code, @RequestParam String oauth2url) {
AccessToken accessToken = QiYeUtil.getAccessToken(Constants.CORPID, Constants.Secret);
HttpSession session = request.getSession();
if (accessToken != null && accessToken.getToken() != null) {
String Userid = getMemberGuidByCode(accessToken.getToken(), code, Constants.AGENTID);
if (Userid != null) {
session.setAttribute("UserId", Userid);
}
}
// 這里簡單處理,存儲到session中
return "redirect:" + oauth2url;
}
/**
* 構造帶員工身份信息的URL
*
* @param corpid
* 企業id
* @param redirect_uri
* 授權后重定向的回調鏈接地址,請使用urlencode對鏈接進行處理
* @param state
* 重定向后會帶上state參數,企業能夠填寫a-zA-Z0-9的參數值
* @return
*/
private String oAuth2Url(String corpid, String redirect_uri) {
try {
redirect_uri = java.net.URLEncoder.encode(redirect_uri, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String oauth2Url = "https://open.weixin.qq.com/connect/oauth2/authorize?
appid=" + corpid + "&redirect_uri=" + redirect_uri
+ "&response_type=code&scope=snsapi_base&state=sunlight#wechat_redirect";
System.out.println("oauth2Url=" + oauth2Url);
return oauth2Url;
}
/**
* 調用接口獲取用戶信息
*
* @param token
* @param code
* @param agentId
* @return
* @throws SQLException
* @throws RemoteException
*/
public String getMemberGuidByCode(String token, String code, int agentId) {
System.out.println("code==" + code + "\ntoken=" + token + "\nagentid=" + agentId);
Result<String> result = QiYeUtil.oAuth2GetUserByCode(token, code, agentId);
System.out.println("result=" + result);
if (result.getErrcode() == "0") {
if (result.getObj() != null) {
// 此處能夠通過微信授權用code還錢的Userid查詢自己本地server中的數據
return result.getObj();
}
}
return "";
}
}
須要驗證OAuth2控制器UserController
package org.oms.qiye.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.oms.qiye.interceptor.OAuthRequired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 須要驗證OAuth2控制器
* @author Sunlight
*
*/
@Controller
public class UserController {
/**
* 載入個人信息,此處加入了@OAuthRequired注解
* @param model
* @return
*/
@RequestMapping(value={"/userInfo.do"})
@OAuthRequired
public String load(HttpServletRequest request,Model model){
System.out.println("Load a User!");
HttpSession session = request.getSession();
model.addAttribute("Userid", session.getAttribute("Userid"));
return "user";
}
}
發起https請求並獲取結果HttpRequestUtil.class
微信企業號調用類 {"errcode":0,"errmsg":"ok"} 此結果表示調用方法成功返回QiYeUtil.class
返回結果處理類Result.class
枚舉EnumMethod.class
以上類不在列出。在其它文章已存在!
處理頁面user.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Model And List</title>
</head>
<body>
<h1>Welcome To SpringMVC! This is OAuth2 UserInfo</h1>
<h3>獲取到的Userid是:${UserId}</h3>
</body>
</html>SpringMVC配置文件:mvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?
> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <context:component-scan base-package="org.oms.qiye.web"></context:component-scan> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 靜態文件處理 --> <mvc:resources mapping="/images/**" location="/images/" /> <mvc:resources mapping="/js/**" location="/js/" /> <mvc:resources mapping="/css/**" location="/css/" /> <!-- OAuth2攔截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 對全部的請求攔截使用/** ,對某個模塊下的請求攔截使用:/myPath/* --> <mvc:mapping path="/**" /> <ref bean="oauth2Interceptor" /> </mvc:interceptor> </mvc:interceptors> <bean id="oauth2Interceptor" class="org.oms.qiye.interceptor.OAuth2Interceptor"> </bean> </beans>
server測試結果圖:

手機微信client測試結果圖:

轉載請注明出處。以免慘不忍睹!
技術交流請增加QQ群:點擊鏈接增加群【微信企業號開發交流】:http://jq.qq.com/?
_wv=1027&k=RgbtOX
