xkrs_work/src/main/java/com/xkrs/controller/WeChatController.java

140 lines
5.9 KiB
Java

package com.xkrs.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xkrs.common.config.ConstantConfig;
import com.xkrs.common.encapsulation.PromptMessageEnum;
import com.xkrs.dao.WeChatCodeDao;
import com.xkrs.model.entity.WeChatCode;
import com.xkrs.utils.HttpClientUtil;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Locale;
import static com.xkrs.common.encapsulation.OutputEncapsulation.outputEncapsulationObject;
/**
* @author XinYi Song
* 微信扫码登录
*/
@RestController
public class WeChatController {
@Resource
private WeChatCodeDao weChatCodeDao;
@GetMapping("/callback")
public String callback(@RequestParam("code") String code, String state) throws Exception {
Locale locale = LocaleContextHolder.getLocale();
try{
//1.获取code值,临时票据,类似于验证码
System.out.println(code);
//2.拿着code请求微信固定的地址,得到两个值access_token和openid
String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
"?appid=%s" +
"&secret=%s" +
"&code=%s" +
"&grant_type=authorization_code";
String accessTokenUrl = String.format(baseAccessTokenUrl,
ConstantConfig.WX_OPEN_APP_ID,
ConstantConfig.WX_OPEN_APP_SECRET,
code);
//请求这个拼接好的地址得到返回的值,现在请求地址,不用浏览器了,用httpclient发送一个请求得到一个返回的地址
String accessTokenInfo = HttpClientUtil.doGet(accessTokenUrl);
//所以我们需要对字符串进行分割,先将字符串转换成map集合,map是key-value结构,再根据map中的key得到结果,这里我们用gson
JSONObject jsonObject = JSON.parseObject(accessTokenInfo);
String access_token =(String) jsonObject.get("access_token");
String openid = (String)jsonObject.get("openid");
//扫码人信息加到数据库中去
//判断数据库中是否存在相同的数据库信息,我们可以根据openid来做判断
WeChatCode byOpenId = weChatCodeDao.findByOpenId(openid);
if (byOpenId ==null){
//member为空,表示数据库中没有相同的信息
//3.拿到access_token和openid,再去请求微信提供固定的地址,获取到扫码人的信息
String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
"?access_token=%s" +
"&openid=%s";
String userInfoUrl = String.format(
baseUserInfoUrl,
access_token,
openid
);
//发送请求
String userInfo = HttpClientUtil.doGet(userInfoUrl);
//获取返回的userInfo字符串的扫描人信息
JSONObject jsonObject1 = JSON.parseObject(userInfo);
System.out.println("------>" + jsonObject1);
//昵称
String nickname =(String) jsonObject1.get("nickname");
//头像
String headimgurl =(String) jsonObject1.get("headimgurl");
Integer sex = (Integer) jsonObject1.get("sex");
String unionid = (String) jsonObject1.get("unionid");
WeChatCode weChatCode = new WeChatCode();
weChatCode.setOpenId(openid);
weChatCode.setNickName(nickname);
weChatCode.setUserPhoto(headimgurl);
weChatCode.setUserSex(sex.toString());
weChatCode.setUnid(unionid);
weChatCodeDao.save(weChatCode);
}
//最后返回我们的首页面
//由于我们在前端中需要显示用户名和头像,所以我们需要使用jwt在地址中传递token
//不能使用cookie,是因为cookie不能跨域访问,会导致值传递失败
//使用jwt根据member对象生成token字符串
//String jwtToken = JwtUtils.getJwtToken(member.getId(), member.getNickname());
return "redirect:http://localhost:3000?openId="+openid;
}catch(Exception e){
return outputEncapsulationObject(PromptMessageEnum.PROCESS_FAIL,"操作失败!",locale);
}
}
/**
* 1.生成微信扫描二维码
* @return
*/
@GetMapping("/weChatScanCodeLogin")
public String getWxCode(){
/*第一种方式:固定地址后面拼参数,参数太多,容易拼错
String url = "https://open.weixin.qq.com/connect/qrconnect?appid="+ ConstantWxUtils.WX_OPEN_APP_ID
+"&response_type=code";
*/
//第二种方式:%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";
//对redirect_url进行URLEnccode编码
String redirect_url =ConstantConfig.WX_OPEN_REDIRECT_URL;
try {
redirect_url = URLEncoder.encode(redirect_url, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
String url =String.format(
baseUrl,
ConstantConfig.WX_OPEN_APP_ID,
redirect_url,
"atguigu"
);
//请求微信地址
return url;
}
}