Vue前端开发——微信登录
1、准备工作1.1 现在微信开放平台注册一个账号https://open.weixin.qq.com/1.2 查看官方文档https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站
·
1、准备工作
1.1 现在微信开放平台注册一个账号
1.2 查看官方文档
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
- 在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程
-
注册帐号和申请应用都是免费的,必须要有一个线上的网站,才能审核通过(过程还是挺麻烦的),就可以使用微信的登录了
-
1.3 登录授权时序图
- AppID 应用ID,唯一标识(身份证号)
- AppSecret 应用的密钥(密码)
- code 授权的临时凭证(例如:临时身份证)
- access_token 接口调用凭证(例如:真正的身份证,虎符,令牌)
2、引入二维码
2.1 在Vue中进行安装
npm install vue-wxlogin
如果不是
vue
的项目,可以直接引用官方提供的
js
文件,来生成二维码
2.2 在Header.vue登录页面引入
<script>
// import wxlogin from 'vue-wxlogin'; // 引入
export default {
name: "Header",
components:{
// wxlogin // 声明引用的组件
},
2.3 引入二维码,首先定义了一个<div id="loginForm">
<!-- 登录表单-->
<div id="loginForm">
<el-form>
<el-form-item>
<h1 style="font-size:30px;color:#00B38A">拉勾</h1>
</el-form-item>
<el-form-item>
<el-input v-model="phone" placeholder="请输入常用手机号..."></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="password" placeholder="请输入密码..."></el-input>
</el-form-item>
</el-form>
<el-button
style="width:100%;margin:0px auto;background-color: #00B38A;font-size:20px"
type="primary"
@click="login">确 定</el-button>
<p></p>
<!-- 微信登录图标 -->
<img
@click="goToLoginWX"
src="http://www.lgstatic.com/lg-passport-fed/static/pc/modules/common/img/icon-wechat@2x_68c86d1.png"
alt=""
/>
</div>
然后引入二维码
<!-- 二维码 -->
<wxlogin id="wxLoginForm" style="display:none"
:appid="appid" :scope="scope" :redirect_uri="redirect_uri">
</wxlogin>
在data中定义
data() {
return {
isLogin: false, // 登录状态,true:已登录,false:未登录
userDTO:null, // 用来保存登录的用户信息
isHasNewMessage: false, // 是否有新的推送消息
dialogFormVisible: false, // 是否显示登录框,true:显示,false:隐藏
phone: "", // 双向绑定表单 手机号
password: "", // 双向绑定表单 密码
appid:"数据", // 应用唯一标识,在微信开放平台提交应用审核通过后获得
scope:"snsapi_login", // 应用授权作用域,网页应用目前仅填写snsapi_login即可
redirect_uri:"数据", //重定向地址,(回调地址)
};
},
在methods中定义
// 微信登录
goToLoginWX() {
// 普通的登录表单隐藏
document.getElementById("loginForm").style.display = "none";
// 显示二维码的容器
document.getElementById("wxLoginForm").style.display = "block";
});
},
2.4 methods中login()方法
login(){ // 前去登录
return this.axios
.get("http://localhost:80/user/login" , {
params:{
phone:this.phone,
password:this.password,
nickname:"",
headimg:""
}
})
.then( (result)=>{
console.log( result );
this.dialogFormVisible = false ; //关闭登录框
this.userDTO = result.data; // 保存返回数据中的用户对象信息
this.isLogin = true; // 更新登录状态
localStorage.setItem("user", JSON.stringify(this.userDTO)); // 将登录成功的对象信息保存到本地储存中
} )
.catch( (error)=>{
this.$message.error("登录失败!");
});
},
2.5 created中
created(){
// 当刷新页面,组件创建成功之后,立刻检测本地储存中是否存在用户对象
this.userDTO = JSON.parse( localStorage.getItem("user") );
if(this.userDTO != null){
this.isLogin = true; // 已登录
}else{
// 去检测微信是否登录过
this.axios
.get("http://localhost:80/user/checkWxStatus")
.then( (result)=>{
this.userDTO = result.data;
this.phone = this.userDTO.content.phone;
this.password = this.userDTO.content.password;
this.login();// 走普通登录
})
.catch( (error)=>{
//this.$message.error("登录失败!");
});
}
},
修改HOSTS文件
文件位置:
C:\Windows\System32\drivers\etc\hosts
回调默认指定的是
80
端口,别忘记将
tomcat
的
8003
端口修改成
80
127.0.0.1 www . pinzhi365 . com
3、IDEA代码
3.1 lagou-edu-web中pom.xml依赖
<!-- 需要使用HttpServletRequest获得参数 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<!-- 需要使用HttpClient发出请求 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
3.2 在commons中封装HttpClientUtil
package commons;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.net.URI;
import java.util.Map;
/**
* @Description: httpclient的封装工具类
*/
public class HttpClientUtil {
public static String doGet(String url) {
return doGet(url,null);
}
/**
* get请求,支持request请求方式,不支持restfull方式
*
* @param url 请求地址
* @param param 参数
* @return 响应的字符串
*/
public static String doGet(String url, Map<String, String> param) {
// 创建httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response =null;
try {
// 创建url
URIBuilder builder = new URIBuilder(url);
if (param != null) {
// 在url后面拼接请求参数
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http get请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpClient.execute(httpGet);
// 从响应对象中获取状态码(成功或失败的状态)
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("响应的状态 = " + statusCode);
// 200表示响应成功
if (statusCode == 200) {
// 响应的内容字符串
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
}finally{
// 释放资源
try {
if (response != null) {
response.close();
}
httpClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return resultString;
}
}
3.3 定义从微信返回的数据对象——定义Token对象,转换为实体类
package entity;
/**
* @Description: 令牌实体类
*/
public class Token {
private String access_token ;//接口调用凭证
private String expires_in;// access_token接口调用凭证超时时间,单位(秒)
private String refresh_token;// 用户刷新access_token
private String openid;// 授权用户唯一标识
private String scope;// 用户授权的作用域,使用逗号(,)分隔
private String unionid;// 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
public String getRefresh_token() {
return refresh_token;
}
public void setRefresh_token(String refresh_token) {
this.refresh_token = refresh_token;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getUnionid() {
return unionid;
}
public void setUnionid(String unionid) {
this.unionid = unionid;
}
public Token() {
}
public Token(String access_token, String expires_in, String refresh_token, String openid, String scope, String unionid) {
this.access_token = access_token;
this.expires_in = expires_in;
this.refresh_token = refresh_token;
this.openid = openid;
this.scope = scope;
this.unionid = unionid;
}
}
3.3 定义WxUser——将json格式的user字符串转换成实体对象,方便存和取
package entity;
/**
* @Description: 微信的用户信息
*/
public class WxUser {
private String openid;// 普通用户的标识,对当前开发者帐号唯一
private String nickname;// 普通用户昵称
private String sex;// 普通用户性别,1为男性,2为女性
private String province;// 普通用户个人资料填写的省份
private String city;// 普通用户个人资料填写的城市
private String country;// 国家,如中国为CN
private String headimgurl;// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
private String privilege;// 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
private String unionid;// 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
public WxUser() {
}
public WxUser(String openid, String nickname, String sex, String province, String city, String country, String headimgurl, String privilege, String unionid) {
this.openid = openid;
this.nickname = nickname;
this.sex = sex;
this.province = province;
this.city = city;
this.country = country;
this.headimgurl = headimgurl;
this.privilege = privilege;
this.unionid = unionid;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getHeadimgurl() {
return headimgurl;
}
public void setHeadimgurl(String headimgurl) {
this.headimgurl = headimgurl;
}
public String getPrivilege() {
return privilege;
}
public void setPrivilege(String privilege) {
this.privilege = privilege;
}
public String getUnionid() {
return unionid;
}
public void setUnionid(String unionid) {
this.unionid = unionid;
}
}
3.4 lagou-edu-dao
Integer register(@Param("phone") String phone, @Param("password") String password,@Param("nickname") String nickname,@Param("headimg") String headimg);
<insert id="register">
insert into `user`
(`name`,portrait,phone,password,create_time,update_time)
values
(#{nickname},#{headimg},#{phone},#{password},sysdate(),sysdate())
</insert>
3.5 lagou-edu-service
Integer register( String phone, String password,String nickname,String headimg);
@Override
public Integer register(String phone, String password, String nickname, String headimg) {
return userDao.register(phone,password,nickname,headimg);
}
3.6 lagou-edu-web
Integer register( String phone, String password,String nickname,String headimg);
WxLoginController
package com.lagou.wx;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lagou.entity.User;
import com.lagou.entity.UserDTO;
import com.lagou.user.UserService;
import commons.HttpClientUtil;
import entity.Token;
import entity.WxUser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Description:
*/
@RestController
@RequestMapping("user")
public class WxLoginController {
@Reference // 远程消费
private UserService userService;
private UserDTO dto = null; // 是否用微信登录成功,dto为null,则尚未登录
@GetMapping("wxlogin")
public String wxlogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 微信官方发给我们一个临时凭证
String code = request.getParameter("code");
System.out.println("【临时凭证】code = " + code);
// 2. 通过code,去微信官方申请一个正式的token(令牌)
String getTokenByCode_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxd99431bbff8305a0&secret=60f78681d063590a469f1b297feff3c4&code=" + code + "&grant_type=authorization_code";
String tokenString = HttpClientUtil.doGet(getTokenByCode_url);
System.out.println("tokenString = " + tokenString);
// 将json格式的token字符串转换成实体对象,方便存和取
Token token = JSON.parseObject(tokenString, Token.class);
// 3. 通过token,去微信官方获取用户的信息
String getUserByToken_url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token.getAccess_token() + "&openid=" + token.getOpenid();
String userinfoString = HttpClientUtil.doGet(getUserByToken_url);
System.out.println("userinfoString = " + userinfoString);
// 将json格式的user字符串转换成实体对象,方便存和取
WxUser wxUser = JSON.parseObject(userinfoString, WxUser.class);
System.out.println("微信昵称 = " + wxUser.getNickname());
System.out.println("微信头像 = " + wxUser.getHeadimgurl());
// 拉勾的业务流程! 需要 手机号(wxUser.getUnionid())和密码(wxUser.getUnionid()),头像和昵称
User user = null;
dto = new UserDTO();
// 检测手机号是否注册
Integer i = userService.checkPhone(wxUser.getUnionid());
if(i == 0){
// 未注册,自动注册并登录
userService.register(wxUser.getUnionid(), wxUser.getUnionid(),wxUser.getNickname(),wxUser.getHeadimgurl());
dto.setMessage("手机号尚未注册,系统已帮您自动注册,请牢记密码!");
user = userService.login(wxUser.getUnionid(), wxUser.getUnionid());
}else{
user = userService.login(wxUser.getUnionid(), wxUser.getUnionid());
if(user == null){
dto.setState(300); //300表示失败
dto.setMessage("帐号密码不匹配,登录失败!");
}else{
dto.setState(200); //200表示成功
dto.setMessage("登录成功!");
}
}
dto.setContent(user);
response.sendRedirect("http://localhost:8080");
return null;
}
@GetMapping("checkWxStatus")
public UserDTO checkWxStatus(){
return this.dto;
}
@GetMapping("logout")
public Object logout(){
this.dto = null;
return null;
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)