微信授权并登陆

news/2024/11/30 1:43:10/

微信授权并登陆

记录自己第一次写微信授权后的成果,以便后续查找学习。
参考文档:

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

1. 先确认接收的参数

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

授权会调用这个网址,用户同意授权后重定向到redirect_uri(即为后台授权的接口路径)处,后台可以接收到两个参数:code和state;通过code可以获取用户openid,state中可以存放自己需要的参数,也可以不存,通过下方方式获取:

String code = request.getParameter("code");
String appid = request.getParameter("state");

在这里因为我的appid需要动态获取,所以把appid放在了state中。

2. 通过code换取网页授权access_token

网址:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code参数:appIdsecretcode

通过get请求调用这个网址后得到JSONObject对象,可以得到access_token和openid:

WeiXinOauth2Token weiXinOauth2Token = new WeiXinOauth2Token();
weiXinOauth2Token.setAccessToken(jsonObject.getString("access_token"));//网页授权接口调用凭证
weiXinOauth2Token.setExpiresIn(jsonObject.getInt("expires_in"));//access_token接口调用凭证超时时间,单位(秒)
weiXinOauth2Token.setRefreshToken(jsonObject.getString("refresh_token"));//用户刷新access_token
weiXinOauth2Token.setOpenId(jsonObject.getString("openid"));//用户唯一标识
weiXinOauth2Token.setScope(jsonObject.getString("scope"));//用户授权的作用域,使用逗号(,)分隔

3. 根据accessToken openid 获得用户信息

网址:https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID参数:access_tokenopenid

通过get请求调用这个网址后得到JSONObject对象,可以得到用户的基本信息:

WeChatUser weChatUser =new WeChatUser();
weChatUser.setOpenid(jsonObject.getString("openid"));//用户的唯一标识
weChatUser.setNickName(jsonObject.getString("nickname"));//用户昵称
weChatUser.setSex(jsonObject.getString("sex"));//用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
weChatUser.setProvince(jsonObject.getString("province"));//用户个人资料填写的省份
weChatUser.setCity(jsonObject.getString("city"));//普通用户个人资料填写的城市
if (jsonObject.getString("headimgurl") != null&& !jsonObject.getString("headimgurl").toString().trim().equals("")) {//用户头像weChatUser.setHeadImgUrl(jsonObject.getString("headimgurl"));
} else {weChatUser.setHeadImgUrl("");
}
StringBuffer privilege = null;//用户特权信息,json 数组,这里为了方便写成了String类型的
List<String> privilegeList = JSONArray.toList(jsonObject.getJSONArray("privilege"), List.class);
for (int i = 0; i < privilegeList.size();i ++) {if (i != privilegeList.size() - 1) {privilege.append(privilegeList.get(i)+",");} else {privilege.append(privilegeList.get(i));}
}
weChatUser.setPrivilege(privilege.toString());
if (jsonObject.get("unionid") != null) {//只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段weChatUser.setUnionId(jsonObject.getString("unionid"));
}

4. 登陆

用户授权获取用户基本信息后保存到用户表,生成用户的用户名和密码:

sysUser.setUsername(weChatUser.getNickName());
String salt = oConvertUtils.randomGen(8);
sysUser.setSalt(salt);
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), weChatUser.getOpenid().substring(weChatUser.getOpenid().length() - 6, weChatUser.getOpenid().length()) + "123456&", salt);
sysUser.setPassword(passwordEncode);

根据用户名和密码产生token,存到redis中,然后重定向到首页:

String password = sysUser.getPassword();
String username = sysUser.getUsername();
// 生成token
String token = JwtUtil.sign(username,password);
redisUtil.set("openID" + token, sysUser.getOpenId());
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
// 设置超时时间
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);
redisUtil.expire("openID" + token, JwtUtil.EXPIRE_TIME / 1000);
// 重定向到首页
response.sendRedirect("");

附:全部后端代码

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.business.entity.WeChatUser;
import org.jeecg.modules.system.entity.SysUser;import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.weixin.entity.ZzInstitutionGzhInfo;
import org.jeecg.modules.weixin.service.IZzInstitutionGzhInfoService;
import org.jeecg.modules.weixin.service.WxTokenService;
import org.jeecg.modules.weixin.vo.WeiXinOauth2Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@RestController
@RequestMapping("/weixin")
@Api(tags = "微信接口")
@Slf4j
public class WeiXinUserController {@Autowiredprivate IZzInstitutionGzhInfoService zzInstitutionGzhInfoService;@Autowiredprivate WxTokenService wxTokenService;@Autowiredprivate ISysUserService sysUserService;@Autowiredprivate RedisUtil redisUtil;@RequestMapping(value = "/wxAuthorize", method = RequestMethod.GET)@ApiOperation("微信授权获取用户信息并登陆")public Result<WeChatUser> wxAuthorize(HttpServletRequest request, HttpServletResponse response) {Result<WeChatUser> result = new Result<>();try {String code = request.getParameter("code");String appid = request.getParameter("state");log.info("========appid="+appid);WeiXinOauth2Token weiXinOauth2Token = null;if (StringUtils.isNotBlank(code)) {// state中保存的是appid,根据appid去表中查找该机构的secret// 此处是因为我的appid和secret需要动态获取,所以进行查询,如果不需要动态获取可以省略此步骤ZzInstitutionGzhInfo zzInstitutionGzhInfo = zzInstitutionGzhInfoService.getInstitutionGzhInfo(appid);// 根据 appid secret code 获取openidweiXinOauth2Token = wxTokenService.getOauth2AccessToken(appid, zzInstitutionGzhInfo.getAppSecret(), code);log.info("========weiXinOauth2Token{}",weiXinOauth2Token);if (weiXinOauth2Token != null) {String accessToken = weiXinOauth2Token.getAccessToken();log.info("==========accessToken="+accessToken);String openid = weiXinOauth2Token.getOpenId();// 根据accessToken openid 获得用户信息WeChatUser weChatUser = wxTokenService.getSNSUserInfo(accessToken, openid);// 授权后登陆SysUser sysUser = sysUserService.getUserByOpenId(openid);if (sysUser == null) {// 保存用户的基本信息sysUser = new SysUser();sysUser.setOpenId(weChatUser.getOpenid());sysUser.setNickname(weChatUser.getNickName());sysUser.setSex(Integer.valueOf(weChatUser.getSex()));sysUser.setProvince(weChatUser.getProvince());sysUser.setCity(weChatUser.getCity());sysUser.setHeadImgUrl(weChatUser.getHeadImgUrl());sysUser.setPrivilege(weChatUser.getPrivilege());sysUser.setUnionid(weChatUser.getUnionId());sysUser.setUsername(weChatUser.getNickName());// 生成用户登录的加盐密码// 可以根据自己需要生成密码,这里就不再展示String salt = oConvertUtils.randomGen(8);sysUser.setSalt(salt);String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), weChatUser.getOpenid().substring(weChatUser.getOpenid().length() - 6, weChatUser.getOpenid().length()) + "123456&", salt);sysUser.setPassword(passwordEncode);sysUserService.save(sysUser);}String password = sysUser.getPassword();String username = sysUser.getUsername();// 根据用户名和密码生成tokenString token = JwtUtil.sign(username,password);redisUtil.set("appId"+token,appid);redisUtil.set("openID" + token, sysUser.getOpenId());redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);// 设置超时时间redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);redisUtil.expire("openID" + token, JwtUtil.EXPIRE_TIME / 1000);// 重定向到首页response.sendRedirect("");// 这里返回数据是因为前台需要,如果不需要可以不写result.setResult(weChatUser);result.success("微信授权获取用户信息并登陆成功");return result;} else {result.setMessage("微信授权获取用户信息并登陆 获取token为空");return result;}} else {result.setMessage("微信授权失败");return result;}} catch (Exception e) {log.error("微信授权登录失败", e.getMessage());}return result;}
}
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.jeecg.modules.business.entity.WeChatUser;
import org.jeecg.modules.weixin.service.WxTokenService;
import org.jeecg.modules.weixin.utils.HttpsX509TrustManager;
import org.jeecg.modules.weixin.vo.WeiXinOauth2Token;
import org.springframework.stereotype.Service;
import net.sf.json.JSONObject;import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.security.SecureRandom;
import java.util.List;@Service
@Slf4j
public class WxTokenServiceImpl implements WxTokenService {/*** 网页授权获取openid* @param appId* @param appSecret* @param code* @return*/@Overridepublic WeiXinOauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {WeiXinOauth2Token weiXinOauth2Token = null;String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";requestUrl = requestUrl.replace("APPID", appId);requestUrl = requestUrl.replace("SECRET", appSecret);requestUrl = requestUrl.replace("CODE", code);JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);if (jsonObject != null) {try {weiXinOauth2Token = new WeiXinOauth2Token();weiXinOauth2Token.setAccessToken(jsonObject.getString("access_token"));weiXinOauth2Token.setExpiresIn(jsonObject.getInt("expires_in"));weiXinOauth2Token.setRefreshToken(jsonObject.getString("refresh_token"));weiXinOauth2Token.setOpenId(jsonObject.getString("openid"));weiXinOauth2Token.setScope(jsonObject.getString("scope"));} catch (Exception e) {weiXinOauth2Token = null;int errorCode = jsonObject.getInt("errcode");String str1 = jsonObject.getString("errmsg");log.error(e.getMessage());}}return weiXinOauth2Token;}private JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {JSONObject jsonObject = null;try {TrustManager[] tm = {new HttpsX509TrustManager()};SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new SecureRandom());SSLSocketFactory ssf = sslContext.getSocketFactory();URL url = new URL(requestUrl);HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();conn.setSSLSocketFactory(ssf);conn.setDoOutput(true);conn.setDoInput(true);conn.setUseCaches(false);conn.setRequestMethod(requestMethod);if (outputStr != null) {OutputStream outputStream = conn.getOutputStream();outputStream.write(outputStr.getBytes("UTF-8"));outputStream.close();}InputStream inputStream = conn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;StringBuffer buffer = new StringBuffer();while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}bufferedReader.close();inputStreamReader.close();inputStream.close();inputStream = null;conn.disconnect();jsonObject = JSONObject.fromObject(buffer.toString());} catch (ConnectException localConnectException) {} catch (Exception localException) {}return jsonObject;}/*** 网页授权获取用户信息* @param accessToken* @param openId* @return*/@Overridepublic WeChatUser getSNSUserInfo(String accessToken, String openId) {WeChatUser weChatUser = null;String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);JSONObject jsonObject = httpsRequest(requestUrl,"GET",null);log.info("=============jsonObject="+jsonObject);if (jsonObject.getString("errcode") != null) {} else {weChatUser =new WeChatUser();weChatUser.setOpenid(jsonObject.getString("openid"));weChatUser.setNickName(jsonObject.getString("nickname"));weChatUser.setSex(jsonObject.getString("sex"));weChatUser.setProvince(jsonObject.getString("province"));weChatUser.setCity(jsonObject.getString("city"));if (jsonObject.getString("headimgurl") != null&& !jsonObject.getString("headimgurl").toString().trim().equals("")) {weChatUser.setHeadImgUrl(jsonObject.getString("headimgurl"));} else {weChatUser.setHeadImgUrl("");}StringBuffer privilege = null;List<String> privilegeList = JSONArray.toList(jsonObject.getJSONArray("privilege"), List.class);for (int i = 0; i < privilegeList.size();i ++) {if (i != privilegeList.size() - 1) {privilege.append(privilegeList.get(i)+",");} else {privilege.append(privilegeList.get(i));}}weChatUser.setPrivilege(privilege.toString());if (jsonObject.get("unionid") != null) {weChatUser.setUnionId(jsonObject.getString("unionid"));}weChatUser.setIsEnabled("1");}return weChatUser;}}

http://www.ppmy.cn/news/806668.html

相关文章

微信小程序登录授权

一般的微信小程序登录都会先前端调用wx.login生成code传给后端&#xff0c;后端通过code获取到openid和session_key并返回给前端&#xff0c;前端调用wx.getUserInfo获取对象参数等信息。 由于需求问题&#xff0c;我所写的小程序登录直接由前端调用wx.login生成code&#xff0…

微信第三方平台授权流程

1&#xff0c;获取第三方平台access_token http请求方式: POST&#xff08;请使用https协议&#xff09; https://api.weixin.qq.com/cgi-bin/component/api_component_token POST数据示例: { "component_appid":"appid_value" , "component_appse…

微信公众账号后台怎么解除小程序_微信小程序解除绑定 微信小程序怎么授权...

该如何注销小程序&#xff1f; 微信小程序目前无法取消&#xff0c;也是微信小程序最脆弱、最无助的地方。如果你确定你不想要这个小程序&#xff0c;你可以转移和改变主题和其中的所有信息&#xff0c;这样你的小程序就会变成别人的小程序&#xff0c;与你无关。相当于取消&am…

如何取消html5微信页面授权,微信授权登录网页管理在哪里看?如何取消授权

现在我们都懒于创建账号&#xff0c;一个是担心日后忘记账号或者密码&#xff0c;再者就是...创建账号真的很烦。所以不少人都会选择网站登录选项中的「微信登录」&#xff0c;直接用微信号登录&#xff0c;方便快捷。但很少人会想到&#xff0c;一旦使用微信登录之后&#xff…

微信小程序授权登录取消授权重新授权处理方法 附可用代码

微信小程序授权登录基本是小程序的标配了&#xff0c;但是官方的demo&#xff0c;取消授权后&#xff0c;就不能再重新点击登录&#xff0c;除非重新加载小程序才可以&#xff0c;这下怎么办&#xff1f; 我们可以先在首页引导用户点击&#xff0c;然后跳转到一个新的页面&…

关于微信授权登录的用户取消-2的问题

之前在做微信授权登录的时候&#xff0c;遇到了用户取消:-2的问题&#xff0c;从网上查了一下&#xff0c;也没有找到什么解决方案&#xff0c;最后自己还是把它解决了&#xff0c;和大家分享一下&#xff0c;弄了半天&#xff0c;原来是自己申请错了&#xff0c;我给申请成了网…

微信第三方授权登录

晚上闲来没事&#xff0c;手里突然痒痒的&#xff0c;突然还是写点东西吧&#xff0c;结果想想&#xff0c;不是去年7月份微信刚公开开放第三方app授权登录&#xff01;结果还是有很多应用纷纷采用这个了&#xff0c;可是实际开发中&#xff0c;并不是如我们想象的那么顺利&…

PDF文件转换成CAD图纸怎么做?简单好用的转换方法分享

CAD文件可以进行更加复杂的编辑&#xff0c;例如添加图层、修改线条颜色和粗细等&#xff0c;而PDF文件则只能进行简单的编辑操作。CAD软件中还可以添加文字注释、标注、尺寸和符号&#xff0c;这些功能大大提高了设计的灵活性和精度。下面给大家分享几种能够将PDF文件转换成CA…