视频演示
1.前端代码(全部)
<template>
<view>
<view>
<button @click="login()">点我进行授权登陆</button>
</view>
<!-- 将我们的通过getUserProfile获取到的用户信息进行一个显示处理 -->
<view>
<img :src="userInfo.avatarUrl">
<text>{{userInfo.nickName}}</text>
</view>
<view>
<text>信息是:{{msg}}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello',
userInfo:{
avatarUrl:'',
nickName:'',
},
msg:'',
}
},
onLoad() {
},
methods: {
login() {
let _this=this;
uni.getUserProfile({
provider: 'weixin',
lang: 'zh_CN',
desc: '获取您的昵称,头像地区以及性别',
success: (res) => {
console.log(res.userInfo);
// 调用我们的uni.login()方法这个方法可以获取到我们的临时code这个code是我们的需要的
uni.login({
provider: 'weixin',
success(res2) {
console.log(res2.code);
_this.userInfo.avatarUrl = res.userInfo.avatarUrl;
_this.userInfo.nickName = res.userInfo.nickName;
const user = {
nickName: res.userInfo.nickName,
avatarUrl: res.userInfo.avatarUrl,
code: res2.code//这个只是我们的临时code
}
//这个是我们的向我们的后台发送我们的请求(在后台获取我们的用户的openid)
uni.request({
method:'POST',
url:'http://localhost:9898/user/wxLogin',
data:user,
success(res) {
console.log(res.data.msg);
_this.msg=res.data.msg
}
})
}
})
}
})
}
}
}
</script>
<style>
</style>
1.getUserProfile()获取用户信息
1.1代码
uni.getUserProfile({
provider:'weixin',
lang:'zh_CN',
desc:'获取您的昵称,头像地区以及性别',
success: (res) => {
console.log(res.userInfo);
}
})
打印的结果
2.获取临时code(调用uni.login())
login() {
let _this=this;
uni.getUserProfile({
provider: 'weixin',
lang: 'zh_CN',
desc: '获取您的昵称,头像地区以及性别',
success: (res) => {
console.log(res.userInfo);
// 调用我们的uni.login()方法这个方法可以获取到我们的临时code这个code是我们的需要的
uni.login({
provider: 'weixin',
success(res2) {
console.log(res2.code);
//将我们的用户的信息渲染到到我们的页面上边去
_this.userInfo.avatarUrl = res.userInfo.avatarUrl;
_this.userInfo.nickName = res.userInfo.nickName;
//封装user对象 传递给我们的后台进行数据的存储
const user = {
nickName: res.userInfo.nickName,
avatarUrl: res.userInfo.avatarUrl,
code: res2.code//这个只是我们的临时code
}
//这个是我们的向我们的后台发送我们的请求(在后台获取我们的用户的openid)
uni.request({
//书写你们自己的真实的地址
url:'',
data:user,
})
}
})
}
})
}
这个是我们的打印出来的临时code
3.开启一个后端项目(springboot)
依赖引入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.sdjzu</groupId>
<artifactId>yt</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>yt</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.29.0</version>
</dependency>
<!-- <!– https://mvnrepository.com/artifact/cn.dev33/sa-token-core –>-->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-core</artifactId>
<version>1.29.0</version>
</dependency>
<!-- <!– hooltools–>-->
<!-- <dependency>-->
<!-- <groupId>cn.hutool</groupId>-->
<!-- <artifactId>hutool-all</artifactId>-->
<!-- <version>5.3.6</version>-->
<!-- </dependency>-->
<!-- <!– https://mvnrepository.com/artifact/cn.dev33/sa-token-servlet –>-->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-servlet</artifactId>
<version>1.29.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!-- <!– https://mvnrepository.com/artifact/cn.dev33/sa-token-oauth2 –>-->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-oauth2</artifactId>
<version>1.29.0</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>1.29.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 添加Httpclient支持 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.40</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.1建表语句
-- auto-generated definition
create table t_wxuserinfo
(
id int auto_increment
primary key,
openid varchar(90) null,
nickName varchar(150) null,
avatarUrl varchar(600) null,
registerDate datetime null,
lastLoginDate datetime null
);
3.2代码自动生成器(方便我们的自己生成我们的表 带有注释 大家自行修改自己的部分就好)
package yt.test.commom;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import java.util.Collections;
/**
* @since 2022-01-26
*/
public class GeneratorServiceEntity {
public static String url = "jdbc:mysql://localhost:3306/login?serverTimezone=GMT%2b8";//填写自己的url
private static final String userName = "root";//自己的userName
private static final String password = "root";//自己的password
//
private static final String outDir = "C:\\Users\\86189\\Downloads\\Music\\test" //选填 填写你自己的项目的路径
//不用动 写死
+ "\\src\\main\\java\\";
//这个直接写出 截止到 Application下
private static final String parentPackage = "com.yt.test";
// todo 书写你们自己的当前的项目的路径
private static final String mapperLocation = "C:\\Users\\86189\\Downloads\\Music\\test" +
//不用动
"\\src\\main\\resources\\mapper\\";
// todo 书写你们自己的表名即可
private static final String tableName = "t_wxuserinfo";
public static void main(String[] args) {
generate();
}
private static void generate() {
FastAutoGenerator.create(url, userName, password)
.globalConfig(builder -> {
builder.author("yt") // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir(outDir); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent(parentPackage) // 设置父包名
.moduleName(null) // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, mapperLocation)); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.entityBuilder().enableLombok();
// builder.mapperBuilder().enableMapperAnnotation().build();
builder.controllerBuilder().enableHyphenStyle() // 开启驼峰转连字符
.enableRestStyle(); // 开启生成@RestController 控制器
builder.addInclude(tableName) // 设置需要生成的表名
.addTablePrefix("t_", "tbl_"); // 设置过滤表前缀
})
// .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
3.3实体类
package com.sdjzu.yt.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@TableName("t_wxUserInfo")
@Data
public class WxUserInfo implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id; // 用户编号
private String openid; // 用户唯一标识
@TableField("nickName")
private String nickName; // 用户昵称
@TableField("avatarUrl")
private String avatarUrl; // 用户头像图片的 URL
@TableField("registerDate")
@JsonSerialize(using = CustomDateTimeSerializer.class)
private Date registerDate; // 注册日期
//这里采用的就是我们的自己定义的json的格式 也就是我们的json的返回的形式
@TableField("lastLoginDate")
@JsonSerialize(using = CustomDateTimeSerializer.class)
private Date lastLoginDate; // 最后登录日期
//wx.login 和 wx.getUserInfo两个方法获取到用户的信息
@TableField(select = false, exist = false)
private String code; // 微信用户code 前端传来的
@TableField("role")
//用户的角色信息
private String role;
}
缺少的CustomDateTimeSerializer类
package com.sdjzu.yt.entity;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class CustomDateTimeSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
gen.writeString(sdf.format(value));
}
}
3.4业务逻辑的书写
servicec层代码
package yt.test.service;
import yt.test.commom.Result;
import yt.test.entity.Wx;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 服务类
* </p>
*
* @author yt
* @since 2022-06-14
*/
public interface IWxService extends IService<Wx> {
//这个结果类 大家可以随意发挥 符合自己实际开发即可
Result Login(Wx wxUserInfo);
}
servicec实现类层代码(核心)
package com.sdjzu.yt.service.impl;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sdjzu.yt.entity.WxUserInfo;
import com.sdjzu.yt.mapper.WxUserInfoMapper;
import com.sdjzu.yt.service.IWxUserInfoService;
import com.sdjzu.yt.util.HttpClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Service("wxUserInfoService")
public class wxImpl extends ServiceImpl<WxUserInfoMapper, WxUserInfo> implements IWxUserInfoService {
//定死 不需要修改
private static final String jscode2sessionUrl = "https://api.weixin.qq.com/sns/jscode2session";
private static final String appid = "wx3a9ec56a038032c8"; //todo 必改 改成自己的appid
private static final String secret = "ffdae995a6d35840558552ac65803e4d";//todo 必改 改成自己的密钥
@Autowired
private WxUserInfoMapper wxUserInfoMapper;
@Autowired
private HttpClientUtil httpClientUtil;
//实现登陆的逻辑
@Override
public SaResult Login(WxUserInfo wxUserInfo) {
String getMessageUrl = jscode2sessionUrl +
"?appid=" + appid + "&secret=" +
secret + "&js_code=" +
wxUserInfo.getCode() +
"&grant_type=authorization_code";
String result = httpClientUtil.sendHttpGet(getMessageUrl);
JSONObject jsonObject = JSON.parseObject(result);
String openid = jsonObject.get("openid").toString();
// todo 至此我们已经获取到openID
// todo 下面书写自己的业务逻辑 随意发挥
//todo 这个是我的业务逻辑 可以参考(较简单)
QueryWrapper<WxUserInfo> wrapper = new QueryWrapper<>();
wrapper.eq("openid", openid);
WxUserInfo user = wxUserInfoMapper.selectOne(wrapper);
if (user == null) {
System.out.println("插入用户");
try {
wxUserInfo.setOpenid(openid);
} catch (Exception e) {
e.printStackTrace();
}
wxUserInfo.setRegisterDate(new Date());
wxUserInfo.setLastLoginDate(new Date());
wxUserInfoMapper.insert(wxUserInfo);
} else {
System.out.println("更新用户");
user.setNickName(wxUserInfo.getNickName());
user.setAvatarUrl(wxUserInfo.getAvatarUrl());
user.setLastLoginDate(new Date());
wxUserInfoMapper.updateById(user);
}
//
StpUtil.login(openid, SaLoginConfig.setExtra(wxUserInfo.getNickName(), wxUserInfo.getAvatarUrl()));
//这里我们获取到了我们的token 一旦发放我们的token 之后我们的token有效期从这里开始生效
String token = StpUtil.getTokenValue();
Map<String, Object> map = new HashMap<>();
map.put("token", token);
SaResult map1 = new SaResult(200, "成功", map);
return map1;
}
@Override
public SaResult UserAuthority(String userRole) {
return null;
}
}