微信企业号OAuth2验证接口实例(使用SpringMVC)

微信企业号OAuth2验证接口(使用SpringMVC)

企业应用中的URL链接(包括自定义菜单或者消息中的链接),可以通过OAuth2.0来获取员工的身份信息。

注意,此URL的域名,必须完全匹配企业应用设置项中的‘可信域名‘,否则获取用户信息时会返回50001错误码。

可信域名设置不包含"http://",只需域名或IP即可。

OAuth2验证可以使用多种方式,此处使用注解方式。设计思路是在需要获取用户信息的GET请求上添加注解,然后在调用的时候判断是否包含此注解,然后做处理流程。

每次请求包含2种情况:

1.不需要获取用户信息,直接跳转到指定视图;

2.需要获取用户信息,此处分2种情况:

a.session中存储了之前获取的用户信息,则直接跳转到指定视图;

b.session中不包含用户信息,则需要构造带回调参数的URL去微信API服务器获取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 ACCESS_TOKEN = "你的企业号_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.ACCESS_TOKEN);
		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查询自己本地服务器中的数据
				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>

服务器测试结果图:

手机微信客户端测试结果图:

转载请注明出处,以免惨不忍睹!

技术交流请加入QQ群:点击链接加入群【微信企业号开发交流】:http://jq.qq.com/?_wv=1027&k=RgbtOX

QQ群:89714226

时间: 2024-10-10 18:46:07

微信企业号OAuth2验证接口实例(使用SpringMVC)的相关文章

微信企业号简单的OAuth2验证接口实例(使用SpringMVC非注解方式)

目前企业号只提供了scope为"snsapi_base"的应用授权作用域,也就是不会跳转到让用户授权的页面. 之前写了使用注解方式验证并获取用户信息的实例,大家不是很理解,问题很多,现在附上简单的验证获取用户信息的实例! 微信企业号OAuth2验证接口实例(使用SpringMVC) OAuth2.0验证需要注意: 1.redirect_uri参数是授权回调地址,也就是说这个地址外网是可以访问的,所以如果使用本地映射服务器的猿们请修改为外网可以访问的地址! 2.配置可信域名,可信域名是1

《微信开发日志》之OAuth2验证接口

OAuth2接口说明: 企业应用中的URL链接(包括自定义菜单或者消息中的链接),可以通过OAuth2.0验证接口来获取员工的身份信息. 通过此接口获取用户身份会有一定的时间开销.对于频繁获取用户身份的场景,建议采用如下方案: 1.企业应用中的URL链接直接填写企业自己的页面地址 2.用户跳转到企业页面时,企业校验是否有代表用户身份的cookie,此cookie由企业生成 3.如果没有获取到cookie,重定向到OAuth验证链接,获取用户身份后,由企业生成代表用户身份的cookie 4.根据c

微信企业号-- OAuth2.0验证.net开发

在做企业号 OAuth2.0验证 的时候走了一些弯路,在这里记录一下. 当我查官方的接口文档的时候就给了一下代码: 企业应用中的URL链接(包括自定义菜单或者消息中的链接),可以通过OAuth2.0验证接口来获取成员的身份信息. 通过此接口获取成员身份会有一定的时间开销.对于频繁获取成员身份的场景,建议采用如下方案: 1.企业应用中的URL链接直接填写企业自己的页面地址 2.成员跳转到企业页面时,企业校验是否有代表成员身份的cookie,此cookie由企业生成 3.如果没有获取到cookie,

asp.net 、C#实现微信企业号OAuth2认证

以微信企业号作为入口的应用,几乎都会遇到需要应用系统中个人信息和微信用户关联问题.从而进行其他业务处理.目前所做项目采取在企业号通讯录添加自定义字段存入应用系统用户信息表中唯一标识UserGuid进行关联.那么如何获取微信企业号通讯录存储的自定义字段.从而实现应用用户信息和微信账号关联?把实现方案大致整理一下,如有不足,还望指出: 1:在企业号通讯录内添加用户Guid唯一字段. 2:创建应用并启用回调模式 3:以微信为入口的应用验证用户的方法,首先在用户访问应用主页时判断Cookie是否有Use

C#开发微信门户及应用(20)-微信企业号的菜单管理

C#开发微信门户及应用(20)-微信企业号的菜单管理 前面几篇陆续介绍了很多微信企业号的相关操作,企业号和公众号一样都可以自定义菜单,因此他们也可以通过API进行菜单的创建.获取列表.删除的操作,因此本篇继续探讨这个主体,介绍企业号的菜单管理操作. 菜单在很多情况下,能够给我们提供一个快速入口,也可以用来获取用户信息的主要入口,通过OAuth2验证接口,以及自定义的重定向菜单,我们就可以获取对应的用户ID,然后进一步获取到用户的相关数据,可以显示给客户. 1.菜单的总体介绍 菜单的事件处理如下所

微信企业号开发:微信用户信息和web网页的session的关系

     微信企业号的用户是须要验证的,因此能关注企业号的用户事实上就是已经通过验证的用户.但企业应用中打开一个网页,在这个网页中怎样依据微信用户的信息创建web应用中最长使用的session呢?微信用户怎样和web的session关联起来呢?    比如:一个应用.依据不同的人员,显示不同的内容,各个网页之间须要session来传递一些信息.在微信企业号中怎样处理呢? 这个问题须要涉及的接口是OAuth2验证接口,须要配置可信域名,初始化session. 一下以一个带有URL的菜单为例进行说明

微信企业号开发:获取AccessToken

微信企业号开发,需要调用微信企业号的相关接口,则必须使用AccessToken,但AccessToken需要corpid,corpsecret两个参数调用相关接口才能获取. 而且每一个接口都有一定的次数限制,当然获取AccessToken的接口也有这个限制.每一个AccessToken的有效期为7200秒,也就是两个小时,在有效期内调用接口,则自动续期.因此建议在获取到AccessToken后,保存在在某一个地方,等到快过期时在重新获取.其实AccessToken有点类似于web程序中的sess

微信企业号:OAuth2.0微信授权验证

企业应用中的URL链接(包括自定义菜单或者消息中的链接),可以通过OAuth2.0验证接口来获取成员的身份信息.使用步骤和方法如下: 1.先开发要使用微信授权认证的网页应用,这个网址必须在互联网上. 2.生成回调网址 企业如果需要员工在跳转到企业网页时带上员工的身份信息,需构造如下的链接: https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_t

微信公众平台企业号验证接口、回调 PHP版

微信公众平台企业号验证接口.回调 PHP版,本人为了解决这个企业号的验证和发送消息的问题,整整研究了几天时间,因为微信企业号刚推出来,网上资料太少了!后来在一些朋友的帮助下和本人反复调试完善下,终于整理得到了比较理想的文档,经亲测,实验成功. include_once "WXBizMsgCrypt.php"; // 第三方发送消息给公众平台 $encodingAesKey = "rpJmhCphnndiCLIcNKcUmhTn2GQBNjISPU9GfsfOlxx"