登录问题

您所在的位置:网站首页 vivo手机怎么用浏览器扫二维码登录微信 登录问题

登录问题

2024-01-03 03:47| 来源: 网络整理| 查看: 265

这篇文章主要说明一下在线教育系统的登录问题 主要介绍 - 单点登录概念、微信扫面登录 (Java 后端)

文章目录 1. 单点登录1.1 简介1.2 常见的三种单点登录方式1.2.1 session 广播机制实现1.2.2 使用 cookie + redis 实现1.2.3 使用 token 实现1.2.4 JWT 2. 登录2.1 普通登录2.2 微信扫描登录2.2.1 OAuth22.2.2 准备工作 2.2.3 生成微信扫描二维码2.2.4 扫描二维码

1. 单点登录 1.1 简介 单点登录 (Single Sign On – SSO)在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统 1.2 常见的三种单点登录方式 1.2.1 session 广播机制实现 登录成功后,把用户数据放到 session 里面;判断是否登录,从 session 中获取数据,可以获取到登录 session.setAttribute("user",user); session.getAttribute("user"); 1.2.2 使用 cookie + redis 实现

在项目中任何一个模块进行登录,登录之后,把数据放到两个地方

redis:在 key 生成唯一随机值(ip、用户id等等);在 value 中存储用户数据 cookie:把 redis 里面生成的 key 值放到 cookie 里面

访问项目中的其他模块,发送请求带着 cookie 进行发送,获取 redis 值

把 cookie 获取值,到 redis 进行查询, 根据 key 进行查询,如果查询到数据就是登录 1.2.3 使用 token 实现

在项目中某个模块进行登录,登录之后,按照一定的规则生成字符串,把登录之后的用户信息包含到生成字符串中,返回字符串

可以把字符串通过 cookie 返回; 把字符串通过地址栏返回

再去访问项目其他模块,每次访问在地址栏带着生成字符串,可以根据地址栏字符串获取用户信息

1.2.4 JWT token 是按照一定规则生成字符串,包含用户信息规则是怎么样的,不一定一般采用官方规则(JWT)

JWT 生成字符串包含三部分:

JWT 头信息;有效载荷,包含主体信息(用户信息);签名哈希(防伪标志) 2. 登录 实现界面 2.1 普通登录 获取登录手机号、密码判断手机号、密码是否为空判断手机号是否正确 – 和数据库中的手机号进行比较判断密码似乎否正确 – 把输入的密码进行加密,再和数据库密码进行比较使用 JWT 工具类,生成并返回 token //登录的方法 @Override public String login(UcenterMember member) { //获取登录手机号和密码 String mobile = member.getMobile(); String password = member.getPassword(); //手机号和密码非空判断 if(StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password)) { throw new GuliException(20001,"登录失败"); } //判断手机号是否正确 QueryWrapper wrapper = new QueryWrapper(); wrapper.eq("mobile",mobile); UcenterMember mobileMember = baseMapper.selectOne(wrapper); //判断查询对象是否为空 if(mobileMember == null) {//没有这个手机号 throw new GuliException(20001,"登录失败"); } //判断密码 //因为存储到数据库密码肯定加密的 //把输入的密码进行加密,再和数据库密码进行比较 //加密方式 MD5 if(!MD5.encrypt(password).equals(mobileMember.getPassword())) { throw new GuliException(20001,"登录失败"); } //登录成功 //生成token字符串,使用jwt工具类 String jwtToken = JwtUtils.getJwtToken(mobileMember.getId(), mobileMember.getNickname()); return jwtToken; } 2.2 微信扫描登录 2.2.1 OAuth2 OAuth2 是针对特定问题一种解决方案主要解决两个问题: 1.开放系统间授权 2.分布式访问问题

开放系统间授权方式:

密码用户名复制、通用开发者key(万能钥匙)、办法令牌

分布式访问(单点登录)

1. 登陆成功之后,按照一定的规则生成字符串,字符串包含用户信息 2. 把生成的字符串通过路径传播,或者cookie 3. 后面再发送请求的时候,每次带着字符串进行发送;获取字符串,从字符串中获取用户信息登录

OAuth2解决方案:令牌机制,按照一定规则生成字符串,字符串中包含用户信息

2.2.2 准备工作 参考官方文档 https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

简而言之:获得 app_id 和 app_secret

# 微信开放平台 -- appid wx.open.app_id=wxed9954c01bb89b47 # 微信开放平台 -- appsecret wx.open.app_secret=a7482517235173ddb4083788de60b90e # 微信开放平台 -- 重定向url wx.open.redirect_url=http://guli.shop/api/ucenter/wx/callback 2.2.3 生成微信扫描二维码 直接请求微信提供固定的地址(向地址后面拼接参数)返回地址(地址中就是二维码) // 生成微信扫描二维码 @GetMapping("login") public String getWxCode() { //固定地址,后面拼接参数 // String url = "https://open.weixin.qq.com/" + // "connect/qrconnect?appid="+ ConstantWxUtils.WX_OPEN_APP_ID+"&response_type=code"; // 微信开放平台授权baseUrl %s相当于?代表占位符 String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" + "?appid=%s" + "&redirect_uri=%s" + "&response_type=code" + "&scope=snsapi_login" + "&state=%s" + "#wechat_redirect"; //对redirect_url进行URLEncoder编码 String redirectUrl = ConstantWxUtils.WX_OPEN_REDIRECT_URL; try { redirectUrl = URLEncoder.encode(redirectUrl, "utf-8"); }catch(Exception e) { } //设置%s里面值 String url = String.format( baseUrl, ConstantWxUtils.WX_OPEN_APP_ID, redirectUrl, "kc" ); //重定向到请求微信地址里面 System.out.println(url); return "redirect:"+url; } 2.2.4 扫描二维码

步骤:

扫描之后,执行本地的 callback 方法,在跳转时传递过来两个值(state-原样传递)(code-类似于手机验证码);

拿到第一步的code,请求微信提供固定的地址,获取两个值;

https://api.weixin.qq.com/sns/oauth2/access_token access_token:访问凭证openid:每个微信唯一的标识

拿到 access_token 和 openid ,再去请求一个微信的固定地址,最终可以得到微信扫描人的信息

https://api.weixin.qq.com/sns/userinfo @Autowired private UcenterMemberService memberService; //2 获取扫描人信息,添加数据 @GetMapping("callback") public String callback(String code, String state) { try { //1 获取code值,临时票据,类似于验证码 //2 拿着code请求 微信固定的地址,得到两个值 accsess_token 和 openid String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" + "?appid=%s" + "&secret=%s" + "&code=%s" + "&grant_type=authorization_code"; //拼接三个参数 :id 秘钥 和 code值 String accessTokenUrl = String.format( baseAccessTokenUrl, ConstantWxUtils.WX_OPEN_APP_ID, ConstantWxUtils.WX_OPEN_APP_SECRET, code ); //请求这个拼接好的地址,得到返回两个值 accsess_token 和 openid //使用httpclient发送请求,得到返回结果 String accessTokenInfo = HttpClientUtils.get(accessTokenUrl); //从accessTokenInfo字符串获取出来两个值 accsess_token 和 openid //把accessTokenInfo字符串转换map集合,根据map里面key获取对应值 //使用json转换工具 Gson Gson gson = new Gson(); HashMap mapAccessToken = gson.fromJson(accessTokenInfo, HashMap.class); String access_token = (String)mapAccessToken.get("access_token"); String openid = (String)mapAccessToken.get("openid"); //把扫描人信息添加数据库里面 //判断数据表里面是否存在相同微信信息,根据openid判断 UcenterMember member = memberService.getOpenIdMember(openid); if(member == null) {//memeber是空,表没有相同微信数据,进行添加 //3 拿着得到accsess_token 和 openid,再去请求微信提供固定的地址,获取到扫描人信息 //访问微信的资源服务器,获取用户信息 String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" + "?access_token=%s" + "&openid=%s"; //拼接两个参数 String userInfoUrl = String.format( baseUserInfoUrl, access_token, openid ); //发送请求 String userInfo = HttpClientUtils.get(userInfoUrl); System.out.println(userInfo); //获取返回userinfo字符串扫描人信息 HashMap userInfoMap = gson.fromJson(userInfo, HashMap.class); String nickname = (String)userInfoMap.get("nickname");//昵称 String headimgurl = (String)userInfoMap.get("headimgurl");//头像 member = new UcenterMember(); member.setOpenid(openid); member.setNickname(nickname); member.setAvatar(headimgurl); memberService.save(member); // 保存新用户 } //使用jwt根据member对象生成token字符串 String jwtToken = JwtUtils.getJwtToken(member.getId(), member.getNickname()); //最后:返回首页面,通过路径传递token字符串 return "redirect:http://localhost:3000?token="+jwtToken; }catch(Exception e) { throw new GuliException(20001,"登录失败"); } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3