uni-app微信公衆号web JS-SDK開發之(zhī)二授權登錄 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 公衆号相關 >

uni-app微信公衆号web JS-SDK開發之(zhī)二授權登錄

發表時(shí)間:2020-9-30

發布人(rén):融晨科技

浏覽次數:99

前言

不(bù)了(le/liǎo)解如何接入JS-SDK的(de)可以(yǐ)先看看上(shàng)篇文章uni-app微信公衆号web JS-SDK開發之(zhī)一接入

目标

  • 通過微信授權登錄到(dào)系統

微信登錄原理

在(zài)這(zhè)裏插入圖片描述
注意上(shàng)面的(de)域名信息

實現微信登錄

先看一下微信文檔了(le/liǎo)解一下:網頁授權

回調域名配置(必須配置,是(shì)頁面不(bù)是(shì)接口)

在(zài)這(zhè)裏插入圖片描述
在(zài)這(zhè)裏插入圖片描述

後端實現code換OpenId

使用weixin-java-mp

maven依賴

 <dependency>
    <groupId>com.github.binarywang</groupId>
     <artifactId>weixin-java-mp</artifactId>
     <version>3.9.0</version>
 </dependency>

我沒用starter版,自己定義更靈活

初始化WxMpService

@Component
public class WxMpServiceDaemon {
    private WxMpService wxMpService;
    private String configHash;

    /**
     * get後不(bù)要(yào / yāo)緩存,因爲(wéi / wèi)會被因配置的(de)改變而(ér)實時(shí)刷新
     */
    public WxMpService getWxMpService() {
        if (StringUtils.isBlank(ProjectWxMpConfigBean.INSTANCE.getAppId())) {
            throw new RuntimeException("未配置公衆号AppId等字段");
        }
        if (StringUtils.isBlank(ProjectWxMpConfigBean.INSTANCE.getSecret())) {
            throw new RuntimeException("未配置公衆号AppSecret等字段");
        }
        String hash = SecureUtil.md5(ProjectWxMpConfigBean.INSTANCE.getAppId() + ProjectWxMpConfigBean.INSTANCE.getSecret() + ProjectWxMpConfigBean.INSTANCE.getToken() + ProjectWxMpConfigBean.INSTANCE.getAesKey());
        if (hash.equals(configHash) && null != wxMpService) {
            //配置未變,使用緩存
            return wxMpService;
        }
        WxMpServiceImpl wxMpService = new WxMpServiceImpl();
        WxMpDefaultConfigImpl conf = new WxMpDefaultConfigImpl();
        conf.setAppId(ProjectWxMpConfigBean.INSTANCE.getAppId());
        conf.setSecret(ProjectWxMpConfigBean.INSTANCE.getSecret());
        conf.setToken(ProjectWxMpConfigBean.INSTANCE.getToken());
        conf.setAesKey(ProjectWxMpConfigBean.INSTANCE.getAesKey());
        wxMpService.setWxMpConfigStorage(conf);
        configHash = hash;
        this.wxMpService = wxMpService;
        return wxMpService;
    }
}

自定義了(le/liǎo)WxMpServiceDaemon來(lái)獲取WxMpService,這(zhè)種方式可以(yǐ)根據配置信息的(de)改變而(ér)實時(shí)刷新WxMpService實現熱更換

code換OpenId

@Component
@Slf4j
public class WxmpAuthServiceImpl implements UserDetailsService {
    @Resource
    private AppUserWriteBiz appUserWriteBiz;
    @Resource
    private AppUserReadBiz appUserReadBiz;

    private Cache<String, String> codeCache = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
    @Resource
    private WxMpServiceDaemon wxMpServiceDaemon;


    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        WxMpOAuth2AccessToken session = null;
        String openId = "";
        synchronized (s.intern()) {
            openId = codeCache.getIfPresent(s);
            if (StringUtils.isBlank(openId)) {
                try {
                    session = wxMpServiceDaemon.getWxMpService().getOAuth2Service().getAccessToken(s);
                } catch (WxErrorException e) {
                    log.error("login by weixin mp error", e);
                    throw new BizException("微信登錄錯誤");
                }
                openId = session.getOpenId();
                codeCache.put(s, openId);
            }

        }

        String finalOpenId = openId;
        AppUser appUser = Optional.ofNullable(appUserReadBiz.getByMpOpenId(openId)).orElseGet(() -> appUserWriteBiz.createMpUser(finalOpenId));
        if (null == appUser) {
            return null;
        }
        return new User(openId, appUser.getPassword(), getAuthorities());
    }

    private Collection<GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authList = new ArrayList<>();
        authList.add(new SimpleGrantedAuthority("ROLE_USER"));
        return authList;
    }
}

這(zhè)裏是(shì)基于(yú)Spring Security OAuth2實現的(de),可以(yǐ)根據關鍵代碼提煉
說(shuō)明一下這(zhè)裏的(de)code即變量s,由于(yú)可能存在(zài)code重複訪問、并發訪問的(de)問題,所以(yǐ)我們加了(le/liǎo)鎖和(hé / huò)使用了(le/liǎo)緩存來(lái)存儲code和(hé / huò)openId關系,但這(zhè)裏注意一下,這(zhè)裏有安全隐患比如code洩露重複獲取登錄token,爲(wéi / wèi)了(le/liǎo)避免這(zhè)樣的(de)問題,我們可以(yǐ)将接口api進行url簽名保證每個(gè)請求的(de)唯一性以(yǐ)及不(bù)可重複性。如果不(bù)想這(zhè)麽麻煩就(jiù)把codeCache給去掉。

相關案例查看更多