首先登录微信开放平台
找到对应开发微信登录的api文档
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.htm
在application.properties中添加
# 微信开放平台 appid
wx.open.app_id=wxed9954c0ttttttttt
# 微信开放平台 appsecret
wx.open.app_secret=a748251723rrrrrrrrrrrrrrrr
# 微信开放平台 重定向url
wx.open.redirect_url=http://guli.shop/api/ucenter/wx/callback
编写赋值实体类
@Component
public class ConstantWxUtils 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;
public static String WX_OPEN_APP_ID;
public static String WX_OPEN_APP_SECRET;
public static String WX_OPEN_REDIRECT_URL;
@Override
public void afterPropertiesSet() throws Exception {
WX_OPEN_APP_ID = appId;
WX_OPEN_APP_SECRET = appSecret;
WX_OPEN_REDIRECT_URL = redirectUrl;
}
}
编写Controller
@CrossOrigin
@Controller //只是请求地址,不需要返回数据,不能用RestController
@RequestMapping("/api/ucenter/wx")
public class WxApiController {
@Autowired
private UcenterMemberService ucenterMemberService;
//一、扫码登录
@GetMapping("login")
public String getWxCode() {
//微信开放平台baseurl,%s相当于?占位符
String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
"?appid=%s" +
"&redirect_uri=%s" +
"&response_type=code" +
"&scope=snsapi_login" +
"&state=%s#wechat_redirect";
String redirectUri = null;
try {
redirectUri = URLEncoder.encode(ConstantWxUtils.WX_OPEN_REDIRECT_URL, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//设置%s里面的值
String url = String.format(baseUrl, ConstantWxUtils.WX_OPEN_APP_ID, redirectUri, "hjh520");
//重定向到微信地址里面
return "redirect:" + url;
}
//二、扫描微信后跳转的地址,通过code获取access_token
@GetMapping("callback")
public String callback(String code, String state) {
try {
//baseAccessTokenUrl,%s相当于?占位符
String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
"?appid=%s" +
"&secret=%s" +
"&code=%s" +
"&grant_type=authorization_code";
//设置%s里面的值
String url = String.format(baseAccessTokenUrl, ConstantWxUtils.WX_OPEN_APP_ID, ConstantWxUtils.WX_OPEN_APP_SECRET, code);
//使用httpClient发送请求,得到返回值
String accessTokenInfo = HttpClientUtils.get(url);
//使用gson将字符串转换成对象
Gson gson = new Gson();
HashMap mapAccessToken = gson.fromJson(accessTokenInfo, HashMap.class);
String accessToken = (String) mapAccessToken.get("access_token");
String openid = (String) mapAccessToken.get("openid");
//判断数据表里面是否存在相同我微信信息,根据openid判断
UcenterMember ucenterMember = ucenterMemberService.getMemberByOponId(openid);
if (ucenterMember == null) {
//第三步:通过access_token调用接口获取用户信息
ucenterMember = getUserInfo(accessToken, openid);
}
//使用JWT生成token
String token = JwtUtils.getJwtToken(ucenterMember.getId(), ucenterMember.getNickname());
//最后:返回首页
//也可以返回token前端自己去跳转页面
return "redirect:http://localhost:3000?token=" + token;
} catch (Exception e) {
new GuliException(20001, "登录失败");
}
return null;
}
/**
* 根据accceToken和openid获取用户信息
*
* @param accessToken
* @param openid
* @return
*/
private UcenterMember getUserInfo(String accessToken, String openid) {
String baseUserUrl = "https://api.weixin.qq.com/sns/userinfo" +
"?access_token=%s" +
"&openid=%s";
//设置%s里面的值
String url = String.format(baseUserUrl, accessToken, openid);
//使用httpClient发送请求,得到返回值
String userInfo = null;
try {
userInfo = HttpClientUtils.get(url);
} catch (Exception e) {
e.printStackTrace();
}
//使用gson将字符串转换成对象
Gson gson = new Gson();
HashMap userInfoMap = gson.fromJson(userInfo, HashMap.class);
String nickname = (String) userInfoMap.get("nickname");//昵称
String headimgurl = (String) userInfoMap.get("headimgurl");//头像
//memmber为空进行添加数据
UcenterMember member = new UcenterMember();
member.setNickname(nickname);
member.setAvatar(headimgurl);
member.setOpenid(openid);
ucenterMemberService.save(member);
return member;
}
}
这里不需要返回数据,只是跳转到微信去,所以使用@Controller ,不能用RestController
项目运行之后,访问地址会跳转到微信二维码页面
当用户用微信扫描之后,将会跳转到配置文件里面配置的路径http://guli.shop/api/ucenter/wx/callback里面去
最后执行localhost:8150/ucenter/wx/callback里面的方法
返回
http://localhost:3000/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJndWxpLXVzZXIiLCJpYXQiOjE2MTE3NDc1ODksImV4cCI6MTYxMTgzMzk4OSwiaWQiOiIxMzU0MzkzNjcyOTEzMjk3NDA5Iiwibmlja25hbWUiOiLlnoLpkpPnmoTlpKfppb_psbwifQ.GE0fkJbLxvbe-PK-FtnkAKLAh57lI1kNBeOv9DbbkvY