微信小程序如何获取token

废话不多说,官方时序图如下:

图里其实说的很清楚了,清理下流程:

1.前端调用wx.login()获取code值

2.前端通过调用wx.getUserInfo获取iv、rawData、signature、encryptedData等加密数据,传递给后端

3.服务器通过code请求api换回session_key和openid

4.服务器通过前端给的rawData 加获取的session_key使用sha1加密,计算出signature1

5.比对前端传的signature和自己算出来的signature1是否一致(防止数据不一致)

6.用AES算法解密encryptedData里的敏感数据

7.拿着敏感数据后做自己的逻辑

8.通知前端登陆成功
第一步:

通过wx.login(微信前端–小程序)接口获取code,将code传到后台

注意:

code的来源:是用户打开小程序的时候,随机生成的,是腾讯生成的,每个code只能使用一次,因此,理论上这个code是安全的

package cn.wmyskxz.springboot.model.user; 
/** * @Author: Yangke * @Date: 2019/3/31 15:52 **/
public class WeChatLoginModel {   
 String code;     
 public String getCode() {        
 return code;    }     
 public void setCode(String code)
  {        
  this.code = code;    
  }}

第二步:
后台通过code访问微信(腾讯)接口,微信(腾讯)接口返回当前登录的信息:session_key及openid

返回的openid是每个用户唯一的,通过这个 可以匹配 微信(腾讯)的用户 跟 我们的用户,就是我们后台通过openid来判断这个人是谁,

在这里插入代码片
/**     * 微信小程序登录     *     
* 登录成功后,将用户身份信息及session_key存入token     
* * @param model     
* * @return     */    
* @ResponseBody    
* @PostMapping("/weChatLogin")    
* public SingleResult<String> weChatLogin
* (@RequestBody WeChatLoginModel model){         
* /**         * 登录日志:         * id\ userid\ date\ wx_code\ createTime         * create table loginLog (                id varchar(50) primary key,                userId varchar(50),                logindate date,                wxcode varchar(100),                createtime datetime           );         */         SingleResult<String> result = new SingleResult<String>();       *  //
* 第三步:调用service.weChatLogin(model):后台检查openid是否存在,返回openid对应的用户        WeChatLoginResult<UserAccount> loginResult = service.weChatLogin(model);       * //*
*  第四步:        UserAccount user = loginResult.getUser();        
* if(user == null ){            
* result.setCode(0);            
* result.setMessage("登录失败");        
* } else {            
* User u = new User(); 
* u.setId(user.getId());            
* u.setPassword(user.getPassword() == null ? user.getWxopenid() : user.getPassword());            
* u.setSessionKey(loginResult.getSession_key());           
*  String token = getToken(u);           
*  result.setToken(token);            
* result.setCode(1);            
* result.setMessage("登陆成功");        
* }         
* return result;   
*  }

其中:就是下面的第三步

//调用service.weChatLogin(model)

WeChatLoginResult loginResult = service.weChatLogin(model);
第三步:

后台检查openid是否存在,
@Override    
public WeChatLoginResult<UserAccount> weChatLogin(WeChatLoginModel model){        WeChatLoginResult<UserAccount> result = null;        
try {             
// code  -> openid            
String urlFormat = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";            
String url = String.format(urlFormat, WeChat.appId, WeChat.secret, model.getCode());            
String json = WeChat.sendGet(url);             
//将json字符串转化成对象            
result = JSON.parseObject(json, WeChatLoginResult.class);             if(result.getErrcode() == null){               
 // 去数据库 检查 openId 是否存在 不存在就新建用户               
  UserAccount user = userAccount.wechatOpenIdIsExists(result.getOpenid());                if(user == null || user.getId() == null){                    
// 不存在,就是第一次登录:新建用户信息                   
user = new UserAccount();                    user.setId(UUID.randomUUID().toString());                    user.setWxopenid(result.getOpenid());                   
user.setLasttime(new Date());                   
userAccount.insert(user); 
}else {                    
//如果存在,就不是第一次登录,更新最后登录时间                    user.setLasttime(new Date());                    userAccount.updateByPrimaryKeySelective(user);               
}                
result.setUser(user);                 
     // 保存登录日志                
LoginLog log = new LoginLog();                log.setId(UUID.randomUUID().toString());               
log.setCreatetime(new Date());               
log.setLogindate(new Date());               
log.setUserid(user.getId());               
log.setWxcode(model.getCode());                
loginLog.insert(log);            
}else { System.out.println(json);            
}catch (Exception e){           
 System.out.println(e.getMessage());        
 }         
return result;    
 }``
@Select("select * from useraccount where wxOpenId = #{wxOpenId}")
UserAccount wechatOpenIdIsExists(String wxOpenId);

(1)如果不存在:就是该用户的第一次登录,后台数据库新添加一个用户信息

如果存在:就不是该用户的第一次登录,以前登陆过,就更新后台数据库中该用户的第一次登录时间

(2) 返回用户信息
第四步:

下发token

//第四步:        UserAccount user = loginResult.getUser();        
if(user == null ){            result.setCode(0);
result.setMessage("登录失败");        }       
 else {            
 User u = new User();            
 u.setId(user.getId());           
  //用户如果是第一次登录,那就是没有密码的,这里用openid当做密码            u.setPassword(user.getPassword() == null ? user.getWxopenid() : user.getPassword());           
   u.setSessionKey(loginResult.getSession_key());           
    //利用User.class中的信息生成token            
    String token = getToken(u);            
    //下发token            
    result.setToken(token);            
    result.setCode(1);           
     result.setMessage("登陆成功");        
     }         
     return result;    
     }
 利用JWT框架生成token

package cn.wmyskxz.springboot.controllers; 
import cn.wmyskxz.springboot.model.User;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm; 
import java.util.Date;
/** * @Author: Yangke * @Date: 2019/3/28 21:12 **/
public abstract class BaseController {     
protected String getToken(User user) {        
String token="";        
token= JWT.create()                .
withKeyId(user.getId())                
.withIssuer("www.ikertimes.com")                .
withIssuedAt(new Date())                .
withJWTId("jwt.ikertimes.com")                .
withClaim("session_key", user.getSessionKey())                .withAudience(user.getId())                .sign(Algorithm.HMAC256(user.getPassword()));        
return token;    
}}

至此,再理一下上面的步骤:

(1)微信小程序通过访问wx.login获得一个code,返回给后台

(2)后台拿着这个code,调用腾讯的接口,获取到openid、seesion-key等信息,openid是用户唯一的

(3)后台拿着openid去数据库中检查,该用户是否是第一次登陆

如果是第一次登陆,那么就新建一个用户–UserAcount;如果不是第一次登陆,就修改该用户的最后登录时间

不管是不是第一次登录,都有了一个用户

(4)然后根据用户的信息利用JWT生成token,下发给微信小程序
第五步

微信小程序收到token后,存起来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值