最早在2007年时Open Authorization提出了OAuth1.0版,在推出五年后,很多开发者们都觉得OAuth1.0开发过程有点复杂,于是就在OAuth1.0基础之上进行改造就有了后来的OAuth2.0。两者的区别在于,OAuth2.0变得更加简单易用,第二个取消了中间的加密过程同时也保留了OAuth1.0中的安全特性。这就是OAuth2.0的基本概念。(相比于OAuth1.0更加简单易用,取消的中间的加密过程且保留了原1.0的安全特性)
时下比较流行的第三方登录,不管是微信登录还是QQ登录,它们采用的标准都是采用OAuth2.0的协议标准。
接下来看一下,OAuth2.0在微信登录过程当中,它是怎么来进行作用的


如果在网页中,用户并不想使用普通的流程去注册登陆,而是用微信登陆的话,那么在登陆页面就会提供一个用于微信登陆的链接,当用户点击微信登陆链接的时候,网页会向微信开发平台发送请求,微信开发平台收到请求之后,会生成一个二维码供用户查看,用户进行微信扫码之后,也就是扫码登陆,会拿到被授权的临时票据(Code),这时拿着票据Code以及在单击微信注册登陆的shi’h获取到的appid及appsecret一共三个参数(Code,appid,appsecret).拿着这三个参数去换取一个时间较长的票据,这个票据被称为access_token,微信中access_token被设置为2个小时的有效期,这个时候我们就可以通过access_token获取用户相应微信用户信息.
步骤如下:
1.用户访问项目(网页登陆页面的微信登陆图标),点击微信登录链接。(调用微信登陆的控制层)
2.在从后台跳转到微信登录页时(携带appid,回调地址),展示给用户登录二维码
3.微信用户扫码进行确认授权,微信平台跳转至回调地址(携带临时票据Code)
4.后台接收到请求,根据临时票据appid和appsecret获取access_token。
5. 项目再根据access_token访问微信登录平台获取用户信息,进行登录
问题:之所以要通过临时票据来得到access_token而不是直接获取access_token,是为了保证数据的更加安全,也为了保证access_token不被泄露。
1.接入条件
1.注册微信开发者平台账号
2.拥有一个已过审核的网站应用
实现方式

  1. 浏览器访问 https://open.weixin.qq.com/
  2. 找到网站应用开发点击下方的蓝色链接进入
  3. 点击创建应用
  4. 没有账号就进行注册(审核过后就会拥有(appid和AppSecret))
  5. 邮箱进行激活注册,然后填写相关企业信息
  6. 通过注册的邮箱账号进行登陆,然后按照第三步骤点击创建应用
    填写相关的信息,提交审核,审核在7个工作日内完成。当完成之后我们即可在项目中编写相关的API接口代码:

    应用官网其实就是你的项目地址,授权回调域也是你的外网访问地址.
    注意:授权回调域前缀不能有http,后缀不能带"/"。
参数 是否必须 说明
appid 应用唯一标识(网站应用审核通过后,会获取到appid和appsecret)
redirect_uri 回调地址,即当用户扫描二维码授权通过后,微信平台要请求网站的URL由它指定。注:需要urlEncode对链接进行处理
response_type 填写code (值固定是code)
scope 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login。
state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验。

**

2. 通过code获取access_token

  1. 获取access_token
    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
  2. 参数说明:

    **
    如果获取正确那么返回的JSON字符串如下:

{
“access_token”:“ACCESS_TOKEN”,
“expires_in”:7200,
“refresh_token”:“REFRESH_TOKEN”,
“openid”:“OPENID”,
“scope”:“SCOPE”,
“unionid”: “o6_bmasdasdsad6_2sgVt7hMZOPfL”
}

参数说明:

错误返回案例:

{“errcode”:40030,“errmsg”:“invalid refresh_token”}

本次代码演示在多模块当中进行布局:
因为是与登陆相关的,所以我将其写在了我的认证模块当中,认证模块就是对登陆用户的认证及Token的处理。如下:

首先在工具类模块中的common目录中导入UrlUtils这个类,然后在认证模块下的controller目录下创建WxLoginController类,这个类就是处理微信登陆的控制层:
1.

1. UrlUtils类中的内容:

package cn.itrip.common;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;/*** 本类提供了对URL所指向的内容的加载操作* @author hduser**/
public class UrlUtils {/*** 获取url网址返回的数据内容* @param urlStr* @return*/public static String loadURL(String urlStr){try{  URL url = new URL(urlStr);  HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();                  urlConnection.setRequestMethod("GET");  urlConnection.connect();              InputStream inputStream = urlConnection.getInputStream(); String responseStr = ConvertToString(inputStream);  return responseStr;}catch(IOException e){  e.printStackTrace(); return null;}}private static String ConvertToString(InputStream inputStream){  InputStreamReader inputStreamReader = new InputStreamReader(inputStream);  BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  StringBuilder result = new StringBuilder();  String line = null;  try {  while((line = bufferedReader.readLine()) != null){  result.append(line + "\n");  }  } catch (IOException e) {  e.printStackTrace();  } finally {  try{  inputStreamReader.close();  inputStream.close();  bufferedReader.close();  }catch(IOException e){  e.printStackTrace();  }  }  return result.toString();  }
}

2.认证模块中的代码:

package cn.itrip.auth.controller.Login;import cn.itrip.common.UrlUtils;
import com.alibaba.fastjson.JSON;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpServletResponse;
import java.util.Map;@Controller
@RequestMapping("/wx/login")
public class WxLoginController {//日志对象private Logger logger = Logger.getLogger(WxLoginController.class);/**** @param code             授权的临时票据* @param state            用于保持请求和回调的状态,授权请求后原样带回给第三方。*                         该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,*                         可设置为简单的随机数加session进行校验。* @param response* @throws Exception*/@RequestMapping(value = "/callBackWeChat",method= RequestMethod.POST)public void callBackWeChat(@RequestParam String code,@RequestParam String state,HttpServletResponse response) throws Exception {/*** 1.编写请求code* 1.1.请求地址* appid=应用唯一标识(网站应用审核通过后,会获取到appid和appsecret)* secret=应用密钥AppSecret,在微信开放平台提交应用审核通过后获得* code=code参数* grant_type=填authorization_code*/String accessUrl="https://api.weixin.qq.com/sns/oauth2/access_token" +"?appid=wx860bf23c66d93e33" +"&secret=9c92026ab4faa4a4f7ac4cf10b2a8a3c" +"&code=" + code +"&grant_type=authorization_code";//1.2通过发送accessUrl请求地址,并得到返回参数,返回的参数是一个json字符串String jsonStr = UrlUtils.loadURL(accessUrl);//将json字符串转换成Map集合Map<String,String> accessMap= JSON.parseObject(jsonStr, Map.class);/*** 2.通过code——access_token获取json字符串/accessMap集合中的accessToken,* 也就是获取集合中的“接口调用凭证”*/String accessToken = accessMap.get("access_token");//3.获取授权用户唯一标识String openId=accessMap.get("openid");logger.info("accessToken的值为:" + accessToken + ",openId的值为:" + openId);//重定向网址response.sendRedirect("http://www.baidu.com");}
}

3. 通过access_token和openid获取当前微信的用户信息

1. 请求地址

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

2. 参数说明:

参数 是否必须 说明
access_token 接口调用凭证
openid 普通用户的标识,对当前开发者帐号唯一(授权用户唯一标识)
lang 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN

3.获取后返回的正确的JSON字符串

{
"openid":"OPENID",
"nickname":"NICKNAME",  #昵称
"sex":1,                 #性别
"province":"PROVINCE",    #省
"city":"CITY",             #市
"country":"COUNTRY",     #国家
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

上述返回的JSON字符串的参数说明:

参数 说明
openid 普通用户的标识,对当前开发者帐号唯一
nickname 普通用户昵称
sex 普通用户性别,1为男性,2为女性
province 普通用户个人资料填写的省份
city 普通用户个人资料填写的城市
country 国家,如中国为CN
headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的

4. 返回错误的JSON字符串

{ “errcode”:40003,“errmsg”:“invalid openid” }

3. 代码编写

对认证模块itripauth中之前编写的WxLoginController类的callBackWeChat方法进行修改,如下:
找到log4j日志输出语句,也就是:

logger.info(“accessToken的值为:” + accessToken + “,openId的值为:” + openId);

1.在这后面通过请求地址获取登陆的微信用户信息也就是 通过access_tokenopenid获取当前微信的用户信息如下:

/**4.通过access_token获取用户信息,参考:资源中心 网站应用微信登录功能授权后接口调用获取用户个人信息(UnionID机制)4.1 请求URL地址
*/
String userInfoUrl="https://api.weixin.qq.com/sns/userinfo?access_token="+ accessToken +"&openid=" + openId;
  1. 发送请求,返回JSON字符串
  2. 获取用户个人信息
String userInfoStr = UrlUtils.loadURL(userInfoUrl);
  1. 获取用户信息中的城市
 Map<String,String> userInfoMap = JSON.parseObject(userInfoStr, Map.class);//3.3 获取用户个人信息String city = userInfoMap.get("city");//获取用户信息中的城市
  1. 获取用户昵称
 String nickname = userInfoMap.get("nickname");
  1. 日志输出这些用户信息
logger.info("city的值为:" + city + ",nickname的值为:" + nickname);

整块代码如下:

logger.info("accessToken的值为:" + accessToken + ",openId的值为:" + openId);//3、通过access_token获取用户信息,参考:资源中心 网站应用微信登录功能授权后接口调用获取用户个人信息(UnionID机制)//3.1 请求URL地址String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId;//3.2 发送请求,返回JSON字符串String userInfoStr = UrlUtils.loadURL(userInfoUrl);Map<String,String> userInfoMap = JSON.parseObject(userInfoStr, Map.class);//3.3 获取用户个人信息String city = userInfoMap.get("city"); //获取用户信息中的城市String nickname = userInfoMap.get("nickname");logger.info("city的值为:" + city + ",nickname的值为:" + nickname);response.sendRedirect("http://www.baidu.com");

这个时候我就在linux服务器上启动sunny-ngrok,通过外网域名访问linux服务器,然后将项目打包放在linux服务器上,之打包当前模块测试运行,如下:
注:要放在对应的tomcat容器上,端口要一致:

启动tomcat之后通过外网域名+项目名访问项目:

这个时候访问微信登陆页面:
https://open.weixin.qq.com/connect/qrconnect?appid=wx860bf23c66d93e33&redirect_uri=http%3a%2f%2fitripDebug.vipgz1.idcfengye.com%2fitripauth%2fwx%2flogin%2fcallBackWeChat&response_type=code&scope=snsapi_login&state=12512#wechat_redirect

参数 说明
appid 应用唯一标识(网站应用审核通过后,会获取到appid和appsecret)

参数 说明
redirect_uri 回调地址,即当用户扫描二维码授权通过后,微信平台要请求网站的URL由它指定。注:需要urlEncode对链接进行处理。对应项目的Controller处理方法地址,上述的地址进行拆分为: redirect_uri**=http%3a%2f%2fitripDebug.vipgz1.idcfengye.com%2fitripauth%2fwx%2flogin%2fcallBackWeChat
第一个加粗的蓝色字体对应我们上述说的启动了sunny-ngrok后的外网域名,第二个加粗的字体也就是itripauth对应了项目名,第三个加粗的字体wx对应了控制层地址,第四个加粗的地址login也对赢了controller地址,第五个callBackWeChat对应了方法名,也就是对应http://itripdebug.vipgz1.idcfengye.com/itripauth/wx/login/callBackWeChat

如下:

可以清楚得看到层次分名的方法调用,根据自己的方法地址更改值即可,
这个时候调用微信登陆扫码页面即可看到成功调用方法,项目配了log4j地址就可在配置地址的log4j日志文件中查看输出的日志信息,如下:

这个时候就说明自己的微信登陆扫码是成功完成了,后续根据项目需要进行数据的存储,如Token,redis这些!!!

SSM框架的Web项目实现微信登陆相关推荐

  1. SSM框架的WEB项目

    工作中我们或多或少都需要自己搭建一个框架,现在常见的Java开源框架组合方式主要为:SSH,spring+springMVC+JDBC,SSM. 其中SSM目前无论是培训机构培训亦或是招聘.都会将会使 ...

  2. SSM框架搭建web项目

    1.SSM框架简介 SSM框架指的是SpringMVC+Spring+MyBatis(连接mysql数据库) 2.配置文件 (1)applicationContext-mvc.xml <?xml ...

  3. ssm框架下web项目,web.xml配置文件的作用(详解)

    1. web.xml中配置了CharacterEncodingFilter,配置这个是拦截所有的资源并设置好编号格式. encoding设置成utf-8就相当于request.setCharacter ...

  4. SSM框架开发web项目系列(四) MyBatis之快速掌握动态SQL

    前言 通过前面的MyBatis部分学习,已经可以使用MyBatis独立构建一个数据库程序,基本的增删查改/关联查询等等都可以实现了.简单的单表操作和关联查询在实际开的业务流程中一定会有,但是可能只会占 ...

  5. 使用maven搭建ssm框架的javaweb项目

    目前主流的javaweb项目,常会用到ssm(Spring+Spring MVC+Mybatis)框架来搭建项目的主体框架,本篇介绍搭建SSM框架的maven项目的实施流程.记之共享! 一.SSM框架 ...

  6. SSM框架基于web的房屋租售管理系统源码+论文第二稿+软件环境+包安装调试

    项目名称 SSM框架基于web的房屋租售管理系统源码 系统说明 用户: 1.首页:系统前台首页使用分块的结构设计进行展示,分别对系统的logo.轮播图.登录注册.新闻公告.最新房源.菜单功能.房屋类型 ...

  7. beego框架 golang web项目-个人博客系统

    beego框架 golang web项目-个人博客系统 beego个人博客系统功能介绍 首页 分页展示博客 博客详情 评论 文章专栏 分类导航 资源分享 时光轴点点滴滴 关于本站 后台管理 登录 系统 ...

  8. ssm框架整合并实现简单验证登陆功能

    ssm框架整合 ssm整合要用到的jar包和配置文件 新建动态web项目, 在web-inf/lib中添加资源中给的所有jar包,并右键依赖项目 添加以下配置文件到src下 将配置文件中的web.xm ...

  9. 实例!使用Idea创建SSM框架的Maven项目

    大家好,我是雄雄,欢迎关注微信公众号[雄雄的小课堂]. 前言 书接前文,昨天带着大家下载且配置了maven,以及在idea中创建maven项目,今天,我们就结合ssm框架,在idea中实现一个增删改查 ...

  10. SSM框架搭建及项目实战

    (可通过图片水印查看博客地址) 1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Ex ...

最新文章

  1. [AlwaysOn Availability Groups]AlwaysOn健康诊断日志
  2. Hugo + Github Pages 搭建个人博客
  3. tomcat android https,tomcat 配置 https, android端 访问
  4. Win10 ancona傻瓜安装tensorflow-gpu,ancona傻瓜安装pytorch-gpu
  5. SECD machine
  6. 我看西电通院月考——学生应该做点什么?
  7. java redis 流水线,Redis系列(1) —— 流水线
  8. python argparse_Python 命令行之旅:argparse、docopt、click 和 fire 总结篇
  9. MCMS 基于SpringBoot 2架构
  10. 从欧拉公式看希尔伯特变换
  11. 01-09 Linux三剑客-awk
  12. JS 与 后台如何获取 Cookies
  13. 关于机器人方面的sci论文_化学教学论文发表【期刊论文】化学教学论文发表
  14. c语言中ftell函数是什么
  15. 基于STC89C51和L298N的42步进电机控制
  16. IDEA插件系列(46):PDF Viewer插件——PDF文档查看器
  17. 小波与小波包、小波包分解与信号重构、小波包能量特征提取 暨 小波包分解后实现按频率大小分布重新排列(Matlab 程序详解)
  18. JAVAEE工程师-2年经验-个人简历
  19. vgp虚拟路面_某车型开发阶段实际道路谱和虚拟路面谱对比分析.pdf
  20. java中vo_java中的vo是什么

热门文章

  1. c#在线考试系统参考文献(精选100个)
  2. Netty中ChannelOption属性含义
  3. 顶尖、顶级、权威期刊目录
  4. iPhone如何快速设置自定义铃声?苹果手机铃声设置教程
  5. Android手机开启开发者模式
  6. 信道——通信原理笔记(二)
  7. python 用泽勒算法计算该天是星期几
  8. 2021年新版python学习课程网盘分享
  9. 眼见不一定为实,电阻、电容和电感的实际等效模型
  10. Php区分自然量跟aso量,ASO优化师该如何判断做优化时下载量与评论的比例关系