作一個開源的小程序登陸模塊組件(token)

先了解下SSO

對於單點登錄淺顯一點的說就是兩種,一種web端的基於Cookie、另外一種是跨端的基於Token,通常想要作的都優先作Token吧,我的建議,由於後期擴展也方便哦。前端

小程序也是呢,作成token的形式是較好的。java

流程圖

圖片描述
PS:圖中4的文字打錯了~git

一、啓動服務
二、小程序初次加載app.js校驗token,使用code去換取token
三、檢測User信息是否存在code,不存在則註冊新用戶,最後返回對應用戶Id
四、將隨機Token與UserId一塊兒存入Redis中
五、返回Token信息,小程序存於緩存中,做爲api請求的認證憑證

這個流程思路對什麼後臺語言都是通用的。github

具體實現

本文的環境主要是作SpringBoot的,全部對於其餘框架可能沒有很好的兼容。

直接上代碼弄起來吧!web

首先是開源的話,咱們須要肯定某些東西是必定要配置的,不能寫死。那麼我寫了兩個Config類來獲取application.yml中的數據,不一樣用戶能夠配置他們的參數。redis

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

我這邊了以上的參數做爲組件中的可配置,其實部分能夠做爲默認的,不過暫時沒有改了,若是你像要使用就是暫時都是必選的。spring

項目目錄

圖片描述
config包中的就是對配置參數的讀取。數據庫

utils包是存放一個Http的請求工具。小程序

最核心的就是咱們的WechatTemplate類了。api

根據業務,咱們須要如下幾個方法:

根據小程序傳遞來的code獲取openid

/**
 * 獲取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;
}

根據openid,咱們能夠和數據庫對接獲得用戶id並生成本身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;
}

還有校驗Token,是否存在

/**
 * 校驗是否存在用戶信息
 * @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包

接着打包發到Maven中央倉庫中,生成本身的maven包

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

如何使用?

我在Github項目中,作了Demo演示。

圖片描述圖片描述

咱們僅需在Service中調用,並使用對應方法便可。

@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:記得添加掃描包路徑,@ComponentScan({"com.github.unclecatmyself"})

GitHub

wechat-login
一個配合小程序登陸的先後臺組件(Token形式),附帶前端小程序代碼


圖片描述

相關文章
相關標籤/搜索