uni-app微信公众号web JS-SDK开发之二授权登录 - 新闻资讯 - 云南小程序开发|云南软件开发|云南网站建设-昆明葵宇信息科技有限公司

159-8711-8523

云南网建设/小程序开发/软件开发

知识

不管是网站,软件还是小程序,都要直接或间接能为您产生价值,我们在追求其视觉表现的同时,更侧重于功能的便捷,营销的便利,运营的高效,让网站成为营销工具,让软件能切实提升企业内部管理水平和效率。优秀的程序为后期升级提供便捷的支持!

您当前位置>首页 » 新闻资讯 » 公众号相关 >

uni-app微信公众号web JS-SDK开发之二授权登录

发表时间:2020-9-30

发布人:葵宇科技

浏览次数:83

前言

不了解如何接入JS-SDK的可以先看看上篇文章uni-app微信公众号web JS-SDK开发之一接入

目标

  • 通过微信授权登录到系统

微信登录原理

在这里插入图片描述
注意上面的域名信息

实现微信登录

先看一下微信文档了解一下:网页授权

回调域名配置(必须配置,是页面不是接口)

在这里插入图片描述
在这里插入图片描述

后端实现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后不要缓存,因为会被因配置的改变而实时刷新
     */
    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;
    }
}

自定义了WxMpServiceDaemon来获取WxMpService,这种方式可以根据配置信息的改变而实时刷新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;
    }
}

这里是基于Spring Security OAuth2实现的,可以根据关键代码提炼
说明一下这里的code即变量s,由于可能存在code重复访问、并发访问的问题,所以我们加了锁和使用了缓存来存储code和openId关系,但这里注意一下,这里有安全隐患比如code泄露重复获取登录token,为了避免这样的问题,我们可以将接口api进行url签名保证每个请求的唯一性以及不可重复性。如果不想这么麻烦就把codeCache给去掉。

相关案例查看更多