1.页面链接发送请求
<a href="http://192.168.1.87:8189/wx_login" style="color:#000;" >手机微信授权</a>
2.后台接受请求
/**
* 手机_微信授权
* @param request
* @param response
*/
@RequestMapping(value = "/wx_login", method = RequestMethod.GET)
public void wxU_login(HttpServletRequest request, HttpServletResponse response){
try {
String state = StringUtilsEx.RandomString(32);
redisService.set("wechat_login", state, 300);
String scope = "snsapi_userinfo";//静默授权 只能获取access_token和openID,流程走完即终止,snsapi_userinfo可以 //获取更详细的用户资料,比如头像、昵称、性别等
String url = URLEncoder.encode("http://api.hestia.me/m/validate/VVIKCNMG9FP/"+"v1/user/callbackphone.do" , "utf-8"); //CALLBACK_DOMAIN为授权回调页面域名
String code_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +APPID
+ "&redirect_uri=" + url + "&response_type=code&scope=" + scope + "&state="+state+"#wechat_redirect";
response.sendRedirect(code_url); //可以获取code 信息并且转发到redirect_uri的地址里
} catch (Exception e) {
e.printStackTrace();
}
}
3.回调(回调地址必须是外网可以访问的)
/**
* 手机_授权回调
* @param request
* @param response
*/
@RequestMapping(value = "/callbackphone", method = RequestMethod.GET)
public void callbackphone(HttpServletRequest request, HttpServletResponse response){
String code_url=null;
String openid =null;
try {
String back_state = request.getParameter("state");
String state =redisService.get("wechat_login");
String code = request.getParameter("code"); //授权时候,微信会吧参数传到这里
if(!StringUtils.equalsIgnoreCase(back_state, state)){
throw new ServiceException("请求无效!");
}
String keys = "wechat_login_code"+code;
if(redisService.exists(keys)){
openid = redisService.get(keys);
}else{
String access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token"+"?appid=" + APPID+ "&secret=" + AppSecret + "&code=" + code + "&grant_type=authorization_code";
String access_token_str;
access_token_str = httpAPIService.doGet(access_token_url);
logger.info("----------->> access_token_str:"+access_token_str);
//logger.info("access_token_str:{},access_token_str:{}",access_token_str,access_token_str);
if(StringUtils.isBlank(access_token_str)){throw new ServiceException("微信授权访问通讯异常!");}
Map tokenmap = JSONUtilsEx.deserialize(access_token_str, Map.class);
if(tokenmap.get("errcode") != null){
throw new ServiceException("获取token失败:"+ObjectUtils.defaultIfNull(tokenmap.get("errmsg"), ""));
}
openid = String.valueOf(tokenmap.get("openid"));
String token = String.valueOf(tokenmap.get("access_token"));
Map<String, String> info = new HashMap<String, String>();
info.put("openid", openid);
info.put("token", token);
redisService.set(keys, openid, 60);
String key = "wechat_login_user"+openid;
redisService.set(key, JSONUtilsEx.serialize(info), 300);
}
code_url =http://192.168.1.79:8090/mywx.shtml?code={code}&openid={openid}&token={token}
//code_url = Infourl.replaceAll("\\{openid\\}", openid);
response.sendRedirect(CommonUtilsEx.parseByExp("\\{(.*?)\\}",url,paramMap).replaceAll("\\{(.*?)\\}", ""));
response.sendRedirect(code_url);
} catch (Exception e) {
e.printStackTrace();
}
}
4.页面接收token ,openid
mywx.shtml
$(function(){
var openid = f_GetQueryString("openid");
var token = f_GetQueryString("token");
if(code && openid){
f_login(openid, token);
}
});
function f_GetQueryString(name){
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
}
然后登录
function f_login(v_openid,v_token){
$.ajax({
url:"http://api.hsjsns.com/ser/v1/user/login",//在这接口根据v_openid,v_token 调用微信接口获取用户信息
contentType:"application/json",
type:"post",
data:JSON.stringify({account:v_openid,pwd:v_token,appid:"H5WG",utype:"U_WX"}),
dataType: "json",
//headers: {"Content-Type":"application/json;charset=UTF-8"},
success: function(data){
console.log(data);
if(data.code==0){
alert(JSON.stringify(data));
var exdate=new Date();
exdate.setDate(exdate.getDate()+3);
CookieUtil.set('hsj_login',(data.data.userId+"_"+data.data.token),exdate.toGMTString(),"","/");
//var v_token=CookieUtil.get('hsj_login',"");
// console.log(v_token);
window.top.location.href="my.shtml";
}
}
});
}
*******************************************
工具
public class JSONUtilsEx {
private static ObjectMapper mapper = new ObjectMapper();
static {
// 设定JSON转化日期的格式
mapper.setDateFormat(new SimpleDateFormat(DateUtilsEx.DATE_FORMAT_SEC));
mapper.setSerializationInclusion(Include.NON_NULL);
// TODO 看是否能转话字典表数据,不行的话只能在前台转化
// mapper.setFilters(filterProvider);
}
/**
* 对象序列化成JSON字符串
* @param obj
* @return
* @throws ServiceException
*/
public static String serialize(Object obj) {
StringWriter writer = null;
try {
writer = new StringWriter();
mapper.writeValue(writer, obj);
writer.close();
} catch (Exception e) {
throw new ServiceException("JSON序列化结果异常:" + e.getMessage());
}
return writer.toString();
}
/**
* JSON字符串反序列化成对象
* @param jsonStr
* @param clazz
* @return
* @throws ServiceException
*/
public static <T> T deserialize(String jsonStr, Class<T> clazz) throws ServiceException {
if (StringUtils.isEmpty(jsonStr)) {
return null;
}
try {
return mapper.readValue(jsonStr.replace("\n", ""), clazz);
} catch (Exception e) {
throw new ServiceException("JSON反序列化结果异常:" + e.getMessage());
}
}
}
************************************************************
public class VerifyUtilsEx {
static String KEY = "RVqq0cifgVJCfeCSxnWU6LoyGIpwYOa6";
static long TIMESTAMP = 5*60; //时间戳5分钟 5*60
/**
* 接口必要参数签名验证
* @return String
* @throws UnsupportedEncodingException
*/
public static String verifyParam(HttpServletRequest request,String[] args) throws UnsupportedEncodingException{
Map params = transToMAP(request.getParameterMap());
return verifyData(params,args);
}
public static String verifyData(Map<String, String> data,String[] args) throws UnsupportedEncodingException{
String sign = "";
String arg_cnt = "";
String msg = "";
if(data == null || data.isEmpty()) return "没有检索到参数!";
for(String arg : args){
if(data.keySet().contains(arg)){
if(data.get(arg)==null || !StringUtils.hasText(String.valueOf(data.get(arg)))){
msg = "参数【"+arg+"】未明确,请确认!";
break;
}
if("sign".equals(arg)){
sign = String.valueOf(data.get(arg));
}
if("ts".equals(arg)){
long systime = System.currentTimeMillis()/1000;
long v_ts = Long.parseLong(data.get(arg));
//时间戳校验
if(Math.abs(systime-v_ts) > TIMESTAMP){
msg = "请求超出有效期!";
break;
}
}
}else{
msg = "参数【"+arg+"】未明确,请确认!";
break;
}
}
//参数都已明确并需要签名验证
if(StringUtils.hasText(sign) && !StringUtils.hasText(msg)){
for(String arg1 : args){
if(!"sign".equals(arg1)){
arg_cnt += String.valueOf(data.get(arg1));
}
}
//System.out.println(URLEncoder.encode(arg_cnt+KEY,"utf-8"));
String v_sign = Md5UtilsEx.getMD5Str(URLEncoder.encode(arg_cnt+KEY,"utf-8").toLowerCase());
//System.out.println(v_sign);
if(!sign.toLowerCase().equals(v_sign.toLowerCase())){
msg = "校验码错误!";
}
}
return msg;
}
private static Map transToMAP(Map parameterMap) throws UnsupportedEncodingException{
// 返回值Map
Map returnMap = new HashMap();
Iterator entries = parameterMap.entrySet().iterator();
Map.Entry entry;
String name = "";
String value = "";
while (entries.hasNext()) {
entry = (Map.Entry) entries.next();
name = (String) entry.getKey();
Object valueObj = entry.getValue();
if(null == valueObj){
value = "";
}else if(valueObj instanceof String[]){
String[] values = (String[])valueObj;
for(int i=0;i<values.length;i++){
value = values[i] + ",";
}
value = value.substring(0, value.length()-1);
}else{
value = valueObj.toString();
}
System.out.println(value);
returnMap.put(name, value);
}
return returnMap;
}
}
*****************************************************************************