步骤:
1. 配置文件
这里配置文件的地址是固定的,另外wx.open.redirect_url这个地址变过一次,下面的是正确地址。还有就是要求service_user端口号为8160。
详情看
wx.open.app_id=wxed9954c01bb89b47
wx.open.app_secret=a7482517235173ddb4083788de60b90e
wx.open.redirect_url=http://localhost:8160/api/ucenter/wx/callback
yygh.baseUrl=http://localhost:3000
2. 配置类
这个配置类写在了util包中,说是配置类,也不是,说是工具类,也不完全是!
@Component
public class ConstantPropertiesUtil implements InitializingBean {
@Value("${wx.open.app_id}")
private String appId;
@Value("${wx.open.app_secret}")
private String appSecret;
@Value("${wx.open.redirect_url}")
private String redirectUrl;
@Value("${yygh.baseUrl}")
private String yyghBaseUrl;
public static String WX_OPEN_APP_ID;
public static String WX_OPEN_APP_SECRET;
public static String WX_OPEN_REDIRECT_URL;
public static String YYGH_BASE_URL;
@Override
public void afterPropertiesSet() throws Exception {
WX_OPEN_APP_ID = appId;
WX_OPEN_APP_SECRET = appSecret;
WX_OPEN_REDIRECT_URL = redirectUrl;
YYGH_BASE_URL = yyghBaseUrl;
}
}
3. controller接口
具体参数要看微信的开发文档:
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
(1)生成二维码代码
@Controller
@RequestMapping("/api/ucenter/wx")
public class WeixinApiController {
@Autowired
private UserInfoService userInfoService;
@Autowired
private RedisTemplate redisTemplate;
/**
* 获取微信登录参数
*/
@GetMapping("getLoginParam")
@ResponseBody
public Result genQrConnect(HttpSession session) throws UnsupportedEncodingException {
String redirectUri = URLEncoder.encode(ConstantPropertiesUtil.WX_OPEN_REDIRECT_URL, "UTF-8");
Map<String, Object> map = new HashMap<>();
map.put("appid", ConstantPropertiesUtil.WX_OPEN_APP_ID);
map.put("redirectUri", redirectUri);
map.put("scope", "snsapi_login");
map.put("state", System.currentTimeMillis()+"");//System.currentTimeMillis()+""
return Result.ok(map);
}
}
(2)扫描二维码回调方法代码
1)添加httpclient工具类
2)controller代码
/**
* 微信登录回调
*
* @param code
* @param state
* @return
*/
@RequestMapping("callback")
public String callback(String code, String state) {
//获取授权临时票据
System.out.println("微信授权服务器回调。。。。。。");
System.out.println("state = " + state);
System.out.println("code = " + code);
if (StringUtils.isEmpty(state) || StringUtils.isEmpty(code)) {
log.error("非法回调请求");
throw new YyghException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
}
//使用code和appid以及appscrect换取access_token
StringBuffer baseAccessTokenUrl = new StringBuffer()
.append("https://api.weixin.qq.com/sns/oauth2/access_token")
.append("?appid=%s")
.append("&secret=%s")
.append("&code=%s")
.append("&grant_type=authorization_code");
String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
ConstantPropertiesUtil.WX_OPEN_APP_ID,
ConstantPropertiesUtil.WX_OPEN_APP_SECRET,
code);
String result = null;
try {
result = HttpClientUtils.get(accessTokenUrl);
} catch (Exception e) {
throw new YyghException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
}
System.out.println("使用code换取的access_token结果 = " + result);
JSONObject resultJson = JSONObject.parseObject(result);
if(resultJson.getString("errcode") != null){
log.error("获取access_token失败:" + resultJson.getString("errcode") + resultJson.getString("errmsg"));
throw new YyghException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
}
String accessToken = resultJson.getString("access_token");
String openId = resultJson.getString("openid");
log.info(accessToken);
log.info(openId);
//根据access_token获取微信用户的基本信息
//先根据openid进行数据库查询
// UserInfo userInfo = userInfoService.getByOpenid(openId);
// 如果没有查到用户信息,那么调用微信个人信息获取的接口
// if(null == userInfo){
//如果查询到个人信息,那么直接进行登录
//使用access_token换取受保护的资源:微信的个人信息
String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
"?access_token=%s" +
"&openid=%s";
String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openId);
String resultUserInfo = null;
try {
resultUserInfo = HttpClientUtils.get(userInfoUrl);
} catch (Exception e) {
throw new YyghException(ResultCodeEnum.FETCH_USERINFO_ERROR);
}
System.out.println("使用access_token获取用户信息的结果 = " + resultUserInfo);
JSONObject resultUserInfoJson = JSONObject.parseObject(resultUserInfo);
if(resultUserInfoJson.getString("errcode") != null){
log.error("获取用户信息失败:" + resultUserInfoJson.getString("errcode") + resultUserInfoJson.getString("errmsg"));
throw new YyghException(ResultCodeEnum.FETCH_USERINFO_ERROR);
}
//解析用户信息
String nickname = resultUserInfoJson.getString("nickname");
String headimgurl = resultUserInfoJson.getString("headimgurl");
UserInfo userInfo = new UserInfo();
userInfo.setOpenid(openId);
userInfo.setNickName(nickname);
userInfo.setStatus(1);
userInfoService.save(userInfo);
// }
Map<String, Object> map = new HashMap<>();
String name = userInfo.getName();
if(StringUtils.isEmpty(name)) {
name = userInfo.getNickName();
}
if(StringUtils.isEmpty(name)) {
name = userInfo.getPhone();
}
map.put("name", name);
if(StringUtils.isEmpty(userInfo.getPhone())) {
map.put("openid", userInfo.getOpenid());
} else {
map.put("openid", "");
}
String token = JwtHelper.createToken(userInfo.getId(), name);
map.put("token", token);
return "redirect:" + ConstantPropertiesUtil.YYGH_BASE_URL + "/weixin/callback?token="+map.get("token")+"&openid="+map.get("openid")+"&name="+URLEncoder.encode((String)map.get("name"));
bug:
bug1:接口1
在接口1,生成二维码接口中,报错:redirect_uricam参数错误
分析:
- swagger测试没错!说明时前端错了!
- 前端中的数据获取要与后端中的名字对应
bug2:接口2
扫码登录一直报错
一直报错!sql异常!
为什么?
原来是我的微信名错误。。HY,你懂得!
请求正常之后的页面:(感觉还是有错误!)
bug3:验证码问题
手机接收验证码说:2分钟内有效。说的是真的。
两分钟之后,验证码从reids中被删除!!!
bug4:总:微信登录问题
目前没有
说明:新用户扫码登录需要注册手机号,往后直接扫码就可以登录成功!
至此,到了133集!