Make an open source applet login module component (token)

First understand the SSO

For the simple sign-on, there are two kinds, one is based on cookies on the web and the other is based on tokens on the cross-end. Generally, what you want to do is to give priority to tokens. Personal advice, because later expansion is also convenient.

The same is true for small programs, which are better made into tokens.

flow chart

image description
PS: The text in the picture 4 is wrong ~

1、启动服务
2、小程序初次加载app.js校验token,使用code去换取token
3、检测User信息是否存在code,不存在则注册新用户,最后返回对应用户Id
4、将随机Token与UserId一起存入Redis中
5、返回Token信息,小程序存于缓存中,作为api请求的认证凭证

This process idea is common to all background languages.

Implementation

The environment of this article is mainly for SpringBoot, so it may not be compatible with other frameworks.

Get it directly on the code!

First of all, if it is open source, we need to make sure that certain things must be configured and cannot be hard-coded. Then I wrote two Config classes to get the data in application.yml, different users can configure their parameters.

wechat:
  wxurl: https://api.weixin.qq.com/sns/jscode2session?
  appid: wxabc2f8828c8e0049
  appsecret: cec2412a3af99200f4573c337715329a
  granttype: authorization_code
  redis:
    expire: 7200
    wxtoken: wx_token_%s
spring:
  redis:
    port: 6379
    host: 192.168.192.132

I have used the above parameters as configurable in the component. In fact, some of them can be used as defaults, but they have not been changed for the time being. If you want to use them, they are all required for the time being.

Project directory

image description
The config package is the reading of configuration parameters.

The utils package is a request tool for storing an Http.

The core is our WechatTemplate class.

According to the business, we need the following methods:

Get openid according to the code passed by the applet

/**
 * 获取OpenId
 * @param code 微信code
 * @return {@link Map}
 */
public Map<String,String> getOpenId(String code){
    Map<String,String> back = new HashMap<>();
    Map<String,String> wxResult = new HashMap<>();
    String wxLoginUrl = weChatComponent.url(code);
    String result = HttpServiceUtils.sendGet(wxLoginUrl);
    if (result.isEmpty()){
        back.put("null","null");
    }else{
        wxResult = (Map) JSON.parse(result);
        if (wxResult.containsKey("errCode")){
            //存在错误码
            back.put("errCode",wxResult.get("errCode"));
        }else{
            //不存在错误码
            String session_key = wxResult.get("session_key");
            back.put("session_key",session_key);
            log.info("【微信Token】session_key:"+session_key);
            String openid = wxResult.get("openid");
            back.put("openid",openid);
        }
    }
    return back;
}

According to openid, we can connect with the database to get the user id and generate our own Token

/**
 * 生成Token
 * @param userid 用户id
 * @return {@link String}
 */
public String granToken(String userid){
    return saveToRedis(userid);
}

/**
 * 获取Token并存放到redis中
 * @param userid 用户id
 * @return {@link String}
 */
private String saveToRedis(String userid) {
    String token = UUID.randomUUID().toString();
    Integer expire = redisComponent.getExpire();
    redisTemplate.opsForValue().set(String.format(redisComponent.getWxtoken(),token),userid,expire, TimeUnit.SECONDS);
    return token;
}

There is also a verification token, whether it exists

/**
 * 校验是否存在用户信息
 * @param token 唯一值
 * @return {@link Boolean}
 */
public boolean verifyToken(String token){
    String tokenValue = redisTemplate.opsForValue().get(String.format(redisComponent.getWxtoken(),token));
    if (tokenValue.isEmpty()){
        return false;
    }
    return true;
}

Maven package

Then package it and send it to the Maven central warehouse to generate your own maven package

<dependency>
  <groupId>com.github.UncleCatMySelf</groupId>
  <artifactId>wechat-login</artifactId>
  <version>2.1.0</version>
</dependency>

how to use?

I did a demo in the Github project.

image descriptionimage description

We only need to call in Service and use the corresponding method.

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private WechatTemplate wechatTemplate;

    @Autowired(required = true)
    private ResultVOUtil resultVOUtil;

    @Override
    public ResultVo getToken(String code) {
        Map<String,String> result = wechatTemplate.getOpenId(code);
        if (result.containsKey("null")){
            return resultVOUtil.error(555,"返回值为空");
        }else if(result.containsKey("errCode")){
            return resultVOUtil.error(666,"存在错误码,内容:"+result.get("errCode"));
        }else{
            String sessionKey = result.get("session_key");
            String openid = result.get("openid");
            log.info("openid="+openid+"--sessionKey="+sessionKey);
            //与存在用户的openid信息进行对比,返回用户id,不存在则注册用户
            String userid = "WX_10agg";//模拟获取到的用户id
            String token = wechatTemplate.granToken(userid);
            return resultVOUtil.success(token);
        }
    }

    @Override
    public ResultVo verifyToken(String token) {
        return resultVOUtil.success(wechatTemplate.verifyToken(token));
    }
}
tip: Remember to add the scan package path, @ComponentScan ({"com.github.unclecatmyself"})

GitHub

Wechat-login is
a front-end and back-end component (Token form) that cooperates with applet login, with front-end applet code


image description

Guess you like

Origin www.cnblogs.com/baimeishaoxia/p/12687205.html