前几期主要针对数据库的设计,mybatis的配置以及mybatis逆向生成代码,以及响应体返回信息封装和全局异常拦截的一些配置拦截处理,文章可能枯燥且看不出任何实际效果。本文将结合前几期的配置进行实战操作!
微信小程序中自带
wx.login
接口,请求该接口会返回一个过期时长为五分钟的code。通过开发者的appid和secret将获取到的code发送请求可以取到openid。最后将 openid作为用户唯一标识主键存入数据库完成注册! 点击查看微信开发者appid和secret
微信小程序的创建本博客将不叙述,点击跳转微信小程序的创建 在index.js中添加如下代码
login(){
// 获取code凭证
wx.login({
success(res){
console.log("wx.login接口得到的数据:",res);
let code = res.code
let userinfo = wx.getStorageSync('userinfo')
userinfo.code = code
// 将code传入后端
wx.request({
url: 'http://127.0.0.1:8080//usercontroller/user',
method:'post',
data : userinfo,
// 后端响应的数据
success(res){
console.log("后端返回的数据:",res);
},
fail(err){
console.log("后端请求失败");
}
})
}
})
},
userinfo(){
let that = this
wx.getUserProfile({
desc:'获取用户信息并登录',
success(res){
console.log("获取到用户信息:",res.userInfo);
wx.setStorageSync('userinfo', res.userInfo)
that.login()
}
})
},
因为官方规定
wx.getUserProfile
接口必须处罚点击事件才能调用。所以还需要wxml来调用userinfo方法!
<!--pages/index/index.wxml-->
<button bindtap="userinfo">登录</button>
效果图如下
若提示
http://127.0.0.1:8080//usercontroller/user
request 合法域名列表中,请按下图操作打开不检验合法域名
后端查询加密后的openid如果存在则直接返回token,如果不存在则新建用户再返回token。
<!--token-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<!-- hutool工具库 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
UserContorller
@RestController
@RequestMapping("usercontroller")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/user")
public BaseResponse login(@RequestBody Map<String,String> params){
return userService.login(params);
}
}
UserService
public interface UserService {
public BaseResponse login(Map<String,String> params);
}
UserServiceImpl
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public BaseResponse login(Map<String,String> params){
String md5_openid = WeChatUtils.GetOpenid(params.get("code"));
// 新账号默认创建房间数量为1,上传视频数量5。若不是新账号则用加密后的openid生成token
User user = User.builder()
.uImg(params.get("avatarUrl"))
.uName(params.get("nickName"))
.openid(md5_openid)
.createRoom(1)
.uploadNum(5)
.build();
// 如果数据库没有这个加密后的openid则注册账号
if (!userDao.openid(md5_openid)){
Assert.isTrue(userDao.addUser(user),"创建用户失败,请联系管理员处理");
}
Map userMap = new HashMap();
userMap.put("token",TokenUtils.sign(user));
return RespGenerator.success(userMap);
}
}
UserDao
public interface UserDao {
public Boolean openid(String md5_openId);
public Boolean addUser(User user);
}
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Autowired
private UserMapper userMapper;
UserExample userExample = new UserExample();
public Boolean openid(String openId){
userExample.createCriteria().andOpenidEqualTo(openId);
return userMapper.selectByExample(userExample).size() < 1 ?false:true;
}
public Boolean addUser(User user){
return userMapper.insert(user) ==1 ?true:false;
}
}
WeChatUtils
public class WeChatUtils {
private static String appid = "wxf9ac121f6797029f";
private static String secret="78ad8f60d3d686eda0822abfc8c8c8f9";
public static String getAppid() {
return appid;
}
public static void setAppid(String appid) {
WeChatUtils.appid = appid;
}
public static String getSecret() {
return secret;
}
public static void setSecret(String secret) {
WeChatUtils.secret = secret;
}
public static String GetOpenid(String code){
String url = "https://api.weixin.qq.com/sns/jscode2session";//指定URL
Map<String, Object> map = new HashMap<>();//存放参数
map.put("appid", WeChatUtils.getAppid());
map.put("secret", WeChatUtils.getSecret());
map.put("js_code",code);
map.put("grant_type","authorization_code");
//发送get请求并接收响应数据
String result= HttpUtil.createGet(url).form(map).execute().body();
return SecureUtil.md5(JSONUtil.parseObj(result).get("openid").toString());
}
}
TokenUtils
@Component
public class TokenUtils {
//token到期时间10小时
private static final long EXPIRE_TIME= 10*60*60*1000;
//密钥盐
private static final String TOKEN_SECRET="ljdyaishi22jin**3nkjnj??";
/**
* 生成token
* @param user
* @return
*/
public static String sign(User user){
String token=null;
try {
Date expireAt=new Date(System.currentTimeMillis()+EXPIRE_TIME);
token = JWT.create()
//发行人
.withIssuer("Ocean_Tan")
//存放数据
.withClaim("md5_openid",user.getOpenid())
//过期时间
.withExpiresAt(expireAt)
.sign(Algorithm.HMAC256(TOKEN_SECRET));
} catch (IllegalArgumentException|JWTCreationException je) {
}
return token;
}
@Autowired
private UserMapper userMapper;
private static TokenUtils tokenUtils;
@PostConstruct
public void inin(){
tokenUtils = this;
}
//解密token并判断用户是否存在
public static Boolean verify(String token){
try {
//创建token验证器
JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("Ocean_Tan").build();
DecodedJWT decodedJWT=jwtVerifier.verify(token);
User user = User.builder().openid(decodedJWT.getClaim("md5_openid").asString()).build();
UserExample userExample = new UserExample();
userExample.createCriteria().andOpenidEqualTo(user.getOpenid());
return tokenUtils.userMapper.selectByExample(userExample).size()==1?true:false;
// System.out.println("过期时间: " + decodedJWT.getExpiresAt());
} catch (IllegalArgumentException |JWTVerificationException e) {
//抛出错误即为验证不通过
// throw new IllegalArgumentException("未获取到用户信息!请登录!");
return false;
}
}
// 解密token并获取token用户信息
public static List<User> tookenList(String token){
JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("Ocean_Tan").build();
DecodedJWT decodedJWT=jwtVerifier.verify(token);
User user = User.builder().openid(decodedJWT.getClaim("md5_openid").asString()).build();
UserExample userExample = new UserExample();
userExample.createCriteria().andOpenidEqualTo(user.getOpenid());
return tokenUtils.userMapper.selectByExample(userExample);
}
}
效果如下图所示