网站应用微信登录
网站应用微信登录
原理:
网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。
获取access_token时序图:
实现:(cv区)
<li>
<a
id="weixin"
class="weixin"
target="_blank"
href="http://localhost:8150/api/ucenter/wx/login"
><i class="iconfont icon-weixin"
/></a>
</li>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.1</version>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!--gson-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
需要替换为公司的微信信息:
wx:
open:
# 微信开放平台 appid
app_id: wxed9954c0********
# 微信开放平台 appsecret
app_secret: a7482517235173ddb40837**********
# 微信开放平台 重定向url(****.****需要在微信开放平台配置)
redirect_url: http://****.****/api/ucenter/wx/callback
JWT原理和JwtUtils.java
/**
* @author Symon
* @version 1.0
* @className WxApiController
* @date 2021/1/8 14:56
*/
@Controller
@RequestMapping("/api/ucenter/wx")
@CrossOrigin
public class WxApiController {
@Value("${wx.open.app_id}")
private String WX_OPEN_APP_ID;
@Value("${wx.open.appsecret}")
private String WX_OPEN_APP_SECRET;
@Value("${wx.open.redirect_url}")
private String WX_OPEN_REDIRECT_URL;
@Resource
private MemberCenterService memberCenterService;
// 1.生成二维码(官方文档第一步)
@GetMapping("login")
public String qrCode() throws Exception{
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 state="abcd";
//对回调路径进行编码
String encodeUrl = URLEncoder.encode(WX_OPEN_REDIRECT_URL, "utf-8");
//拼接字符串
String qrCodeUrl = String.format(baseUrl, WX_OPEN_APP_ID, encodeUrl, state);
return "redirect:" qrCodeUrl;
}
@GetMapping("callback")
public String callback(String code,String state) throws Exception{
//a.通过code appid appsecret得到用户的access_token和openid(官方文档第二步)
String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token"
"?appid=%s"
"&secret=%s"
"&code=%s"
"&grant_type=authorization_code";
//拼接字符串
baseAccessTokenUrl = String.format(baseAccessTokenUrl, WX_OPEN_APP_ID, WX_OPEN_APP_SECRET, code);
String retVal = HttpClientUtils.get(baseAccessTokenUrl);
//把json字符串转换为Java对象
Gson gson = new Gson();
HashMap infoMap = gson.fromJson(retVal, HashMap.class);
String accessToken =(String) infoMap.get("access_token");
String openId =(String) infoMap.get("openid");
//b.根据access_token和openid获取用户信息(官方文档第三步)
String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo"
"?access_token=%s"
"&openid=%s";
//拼接字符串
userInfoUrl = String.format(userInfoUrl, accessToken, openId);
String userInfoJson = HttpClientUtils.get(userInfoUrl);
HashMap userInfoMap = gson.fromJson(userInfoJson, HashMap.class);
String nickName =(String) userInfoMap.get("nickname");
String headImgUrl =(String) userInfoMap.get("headimgurl");
// ......
//c.拿到用户的个人信息 需要存储起来 存之前先判断该用户是否已经在数据库中有了
MemberCenter existMember=memberCenterService.queryUserByOpenId(openId);
if(existMember==null){
existMember = new MemberCenter();
existMember.setOpenid(openId);
existMember.setNickname(nickName);
existMember.setAvatar(headImgUrl);
memberCenterService.save(existMember);
}
//d.返回一个token给前端
String token = JwtUtils.geneJsonWebToken(existMember);
return "redirect:http://127.0.0.1:3000?token=" token;
}
}
参数说明:
// 1.生成二维码(官方文档第一步)
// a.通过code appid appsecret得到用户的access_token和openid(官方文档第二步)
// b.根据access_token和openid获取用户信息(官方文档第三步)
获取用户个人信息(UnionID机制)
请求说明
http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
access_token | 是 | 调用凭证 |
openid | 是 | 普通用户的标识,对当前开发者账号唯一 |
lang | 否 | 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN |
返回说明
正确的Json返回结果:
{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数 | 说明 |
---|---|
openid | 普通用户的标识,对当前开发者账号唯一 |
nickname | 普通用户昵称 |
sex | 普通用户性别,1为男性,2为女性 |
province | 普通用户个人资料填写的省份 |
city | 普通用户个人资料填写的城市 |
country | 国家,如中国为CN |
headimgurl | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 |
privilege | 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) |
unionid | 用户统一标识。针对一个微信开放平台账号下的应用,同一用户的unionid是唯一的。 |
赞 (0)