讲信修睦网

微信公众平台测试号申请、使用HBuilder X与微信开发者工具实现授权登陆功能以及单点登录

微信公众平台测试号申请、使用HBuilder X与微信开发者工具实现授权登陆功能以及单点登录

测试账号申请

测号响应流程:客户端发送请求,微信微信微信服务器收到请求后,公众转发到开发者服务器上,平台处理完后在发送给微信服务器,测试在返回给客户端

1、号申打开微信公众平台,请使权登点击测试帐号申请。具实地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?现授t=sandbox/login,

通过微信扫一扫授权就能进入到测试号管理页面。陆功可以看到自己的单点登录开发者ID

测试号中的url需要自己有服务器编写对应接口,点击提交微信会像url发送数据根据返回结果判断url是微信微信否配置成功;token为自己定义的字符串

最后在扫码添加自己微信为开发者

下载中转工具NATAPP-内网穿透 基于ngrok的国内高速内网映射工具

下载后在网页注册,进行实名认证,公众申请免费隧道,平台会生成隧道信息,测试启动natapp,号申

输入 natapp -authtoken 隧道信息生成的authtoken 回车

这时就会生成自己的域名,在测试时需要一直开启natapp

若是有企业公众号那么就不用以上步骤,直接配置开发者WX即可

创建小程序测试:使用微信开发者工具通过扫码登陆,点击创建选择小程序即可,AppID为刚才申请的。选择需要编写的模板即可

使用HBuilder X与微信开发者工具实现授权登陆功能

首先需要在HBuilder上导入项目模板,在设置安全中配置微信开发者工具的目录,然后点击运行到小程序模拟器,这样运行之后就会自动打开微信开发者工具

创建登陆页面主要代码login.vue,主要是调用微信提供的api获取用户的code,这在前端同时还获取了用户的基本信息发送给后端

//对应逻辑methods: { 			wxlogin(){ 			uni.getUserProfile({ 					desc:"获取资料",					success: (res) =>{ 						console.log(res)						this.encryptedData=res.encryptedData						this.rawData=res.rawData						this.iv=res.iv						this.signature=res.signature						this.avatarUrl=res.userInfo.avatarUrl						this.name=res.userInfo.nickName					}				});//获取用户资料				uni.login({ 				  provider: 'weixin',				  success: (res) =>{ 										 this.code=res.code;					// console.log(this.code);									  }				});				console.log(this.name)				console.log(this.avatarUrl)				//发送请求				uni.request({ 					url:"http://localhost:8081/api/dsxs/company/token",					method:"POST",				 data: { 					// encryptedData:this.encryptedData,					// rawData:this.rawData,					// iv:this.iv,					// signature:this.signature,					code:this.code,					img:this.avatarUrl,					name:this.name				    },					success: (e) =>{ 												console.log("向后端请求成功");					}									})			},

后端可以通过之前申请的appID、appSecret和前端传来的code获取到用户的openID与session_key

创建springboot项目,添加依赖

com.squareup.okhttp3okhttp            4.7.2org.springframework.bootspring-boot-starter-test            testcom.baomidoumybatis-plus-boot-starter            3.3.1mysqlmysql-connector-java        org.projectlomboklombok        org.springframework.bootspring-boot-starter        org.springframework.bootspring-boot-starter-web        com.baomidoumybatis-plus-generator            3.3.1org.apache.velocityvelocity-engine-core            2.0com.alibabafastjson            1.2.62io.jsonwebtokenjjwt            0.9.1org.apache.httpcomponentshttpclient            4.3.1commons-iocommons-io            2.6commons-langcommons-lang            2.6

配置好实体类与数据相关代码后,将自己的appID、appSecret放在配置文件中

wx.open.app_id=xxxxxxxxwx.open.app_secret=xxxxxxxxx

创建获取配置信息类

@Component//@PropertySource("classpath:application.properties")public class ConstantPropertiesUtil implements InitializingBean {     //读取配置文件并赋值    @Value("${ wx.open.app_id}")    private String appId;    @Value("${ wx.open.app_secret}")    private String appSecret;    public static String WX_OPEN_APP_ID;    public static String WX_OPEN_APP_SECRET;    @Override    public void afterPropertiesSet() throws Exception {         WX_OPEN_APP_ID = appId;        WX_OPEN_APP_SECRET = appSecret;    }}

编写用户登录控制层,这里我的实现逻辑是根据前端传来的code,获取用户openID作为用户的唯一标识。首先在数据库中查询有无当前用户,要有创建token返回给前端对应信息。因为前端写的是一次性将code与用户信息全传过来,用户点击登陆后会跳转到授权页面,用户若点击拒绝那么用户信息将不会传过来,只有code,这时我的处理逻辑是判断有无用户信息,若没有不存如数据库,这里由于用户点击授权会有时间响应所以做了一个短暂的休眠处理。

public class LoginController {     @Autowired    private UserService userService;    @PostMapping("token")    public R login(@RequestBody LoginBO loginBO) throws IOException, InterruptedException {     //拼接对应信息        StringBuffer baseAccessTokenUrl = new StringBuffer()                .append("https://api.weixin.qq.com/sns/jscode2session")                .append("?appid=%s")                .append("&secret=%s")                .append("&js_code=%s")                .append("&grant_type=authorization_code");        String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),                ConstantPropertiesUtil.WX_OPEN_APP_ID,                ConstantPropertiesUtil.WX_OPEN_APP_SECRET,                loginBO.getCode());         //像网站发送请求        OkHttpClient client = new OkHttpClient();        Request request = new Request.Builder().url(accessTokenUrl).build();        Response response = client.newCall(request).execute();        //请求成功会返回对应信息,解析为json        if (response.isSuccessful()){             String body = response.body().string();            JSONObject jsonObject = JSONObject.parseObject(body);            String session_key = jsonObject.getString("session_key");            String openid = jsonObject.getString("openid");            HashMapmap = new HashMap<>();            Thread.sleep(1000);            //判断数据中有无当前用户            User userInfo = userService.getByOpenId(openid);            if (userInfo==null){                 User user = new User();                user.setOpenid(openid);                if (loginBO.getName().equals("")){                     return R.error().message("授权失败");                }                user.setNickName(loginBO.getName());                user.setAvatarUrl(loginBO.getImg());                user.setStat(1);                userService.save(user);                userInfo = userService.getByOpenId(openid);            }                String token = JwtHelper.createToken(userInfo.getOpenid(),userInfo.getNickName(),userInfo.getAvatarUrl());                map.put("token",token);                map.put("nickname",userInfo.getNickName());                map.put("img",userInfo.getAvatarUrl());                return R.ok().data(map);        }        return R.error().message("授权失败,请重试");    }

创建JWT生成token工具类

public class JwtHelper {     //过期时间  毫秒    private static long tokenExpiration = 60*60*1000;    //自定义秘钥    private static String tokenSignKey = "123456";    public static String createToken(String openid,String nickName,String img) {         String token = Jwts.builder()                //设置分组                .setSubject("DSXS-USER")                //设置字符串过期时间                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))                //私有部分                .claim("userId", openid)                .claim("userName", nickName)                .claim("img",img)                //设置秘钥                .signWith(SignatureAlgorithm.HS512, tokenSignKey)                .compressWith(CompressionCodecs.GZIP)                .compact();        return token;    }    //从生成token字符串获取userId值    public static String getUserId(String token) {         if(StringUtils.isEmpty(token)) return null;        JwsclaimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);        Claims claims = claimsJws.getBody();        String userId = (String)claims.get("userId");        return (String)claims.get("userId");    }    public static String getUserName(String token) {         if(StringUtils.isEmpty(token)) return "";        JwsclaimsJws                = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);        Claims claims = claimsJws.getBody();        return (String)claims.get("userName");    }    public static String getImg(String token) {         if(StringUtils.isEmpty(token)) return "";        JwsclaimsJws                = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);        Claims claims = claimsJws.getBody();        return (String)claims.get("img");    }

创建根据token获取用户信息方法

//根据token获取用户信息    @GetMapping("auth/getUserInfo")    public R getUserInfo(HttpServletRequest request) {         try{             String userId = AuthContextHolder.getUserId(request);            String userName = AuthContextHolder.getUserName(request);            String userImg = AuthContextHolder.getUserImg(request);            User user = new User();            user.setOpenid(userId);            user.setNickName(userName);            user.setAvatarUrl(userImg);            return R.ok().data("userInfo",user);        }catch (ExpiredJwtException e){             System.out.println("token失效");        }        return R.error().message("token失效");    }

若有其他实现方式欢迎讨论

未经允许不得转载:讲信修睦网 » 微信公众平台测试号申请、使用HBuilder X与微信开发者工具实现授权登陆功能以及单点登录