用户三方登录之微信登录

  • 前端门户点击微信登录扫码发起微信授权请求
  • 跳转回调页面解析url中的code和state
  • 将code与绑定页面的url封装成参数传递到后台
  • 向后台发送登录请求
  • 后台初始controller用post请求方法接收参数,用map来接收传过来的参数,避免创建对象。
  • 调用service层微信登录方法
  • service层做处理获取参数code授权码和绑定页面url地址binderUrl
  • 然后准备请求,获取access_token,和openid
  • 通过准备的httpClient工具类来发送请求,获取
  • 接收发送请求获取的json字符串
  • 将json字符串转化成json对象
  • 通过json对象获取access_token和openid
  • 然后通过openid查询微信用户
  • 如果微信用户不为空并且微信用户的字段User_id不为空就是已经绑定了用户的
  • 直接免密登录
  • 成功一个随机数uToken将uToken和user存到redis里面,并设置过期时间
  • 注意要将user转换成功json字符串对象才可以存到redis里面
  • 然后使用map对象添加到map中传到前台
  • 返回成功并且传uToken和user到前台
  • 前台就弹出提示登录成功,并且将uToken和user都存在localstoage里面。然后跳转主页
  • 如果通过openid查询的微信用户为空就返回失败并且传值bindderUrl到前台,
  • 注意binderUrl地址将access_token和openid传到前台去了
  • 前台接收到返回类型是失败就跳转绑定页面进行绑定。
  • 前台绑定页面输入用户名和密码进行绑定
  • 将参数username,password,还有通过url传到前台的access_token,openid封装到一个变量里面传到后台。
  • 发送绑定请求,并传参
  • 后台controller响应请求使用map对象接收参数
  • 调用service绑定方法
  • service层接收参数username,password,accessToken,openid
  • 准备url请求,获取微信用户信息
  • 通过准备的工具类发送请求,接收参数
  • 将接收的json字符串转换成json对象
  • 将json对象转换成功WechatUser对象
  • 通过参数username去查询数据库是否有该用户
  • 如果有就去判断密码输入是否正确
  • 输入的密码加上数据库的盐值通过MD5加密和数据库的密码比较
  • 如果密码相同就免密登录
  • 不同就返回false
  • 如果用户不存在那就新建一个用户
  • 绑定微信用户字段的user_id
  • 最后免密登录
  • 随机生成一个token
  • 将token和user存在redis中并且设置过期时间
  • 使用map对象将token和user传到前台
  • 返回成功并传递token和user
  • 前台将token和user存在localstoage里面
  • 跳转主页
    主要代码如下
Controller层
/**
     * 微信登录
    */
    @PostMapping("/weChat")
    public AjaxResult weChatLogin(@RequestBody Map<String,String> map){
        return userService.weChatLogin(map);
    }
    /**
     * 绑定用户
     */
    @PostMapping("/binder")
    public AjaxResult Binder(@RequestBody Map<String,String> params){
        return  userService.binder(params);
    }
  Service层
  /**
     * 微信登录
     * @param map
     * @return
     */
    @Override
    public AjaxResult weChatLogin(Map<String, String> map) {
        //获取参数 code binder
        String code = map.get("code");
        String binderUrl = map.get("binderUrl");
        //发送请求获取openid和token
        //准备url
        String url = WechatConstant.GET_OPENID_URL.replace("APPID", WechatConstant.APPID)
                .replace("SECRET", WechatConstant.SECURITY).replace("CODE", code);
        //System.out.println(url);
        //发送请求   返回一个json字符串
        String jsonStr = HttpClientUtil.htppGet(url);
        //把字符串转换成json
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        System.out.println(jsonObject);
        //获取 access_token和openid
        String access_token = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");
        //判断用户是否已经绑定
        //通过openid查询微信用户  然后在去查询微信用户的user_id是否有值,如果有值就说明绑定了的  没有值就没有绑定
        WeChatUser weChatUser=weChatUserService.getWeChatUserByOpenId(openid);
        if(weChatUser!=null&&weChatUser.getUser_id()!=null){
            //通过user_id查询用户
            User user = userMapper.loadById(weChatUser.getUser_id());
            //把uToken存放在redislimian
            String uToken = UUID.randomUUID().toString();
            //存在redis   JSONObject.toJSONString(user)把java对象转化成json格式的字符串
            RedisUtils.INSTANCE.set(uToken,JSONObject.toJSONString(user),30*60);
            //把uToken和user都返回给前台
            Map<String,Object> resultObj=new HashMap<>();
            resultObj.put("uToken",uToken);
            resultObj.put("user",user);
            return AjaxResult.me().setResultObj(resultObj);
        }else {
            //跳转绑定界面
            binderUrl=binderUrl+"?access_token="+access_token+"&openId="+openid;
            return AjaxResult.me().setSuccess(false).setMessage("binder").setResultObj(binderUrl);
        }
    }

    /**
     * 微信登录绑定用户
     * @param params
     * @return
     */
    @Override
    public AjaxResult binder(Map<String, String> params) {
        //获取参数
        String username = params.get("username");
        String password = params.get("password");
        String accessToken = params.get("accessToken");
        String openId = params.get("openId");
        //获取微信用户
        //准备url发送获取
        String url = WechatConstant.GET_WXUSER_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
        //发送请求获取微信用户
        String JsonStr = HttpClientUtil.htppGet(url);
        //将JsonStr转换成微信用户
        WeChatUser weChatUser=JsonStr2WeChatUser(JsonStr);
        //通过用户名去查询用户  如果有就验证密码直接绑定
        User user = userMapper.loadByUsername(username);

        if(user!=null){
            String salt = user.getSalt();
            String wxpassword = MD5Utils.encrypByMd5(password + salt);
            if(!user.getPassword().equals(wxpassword)) {
                return AjaxResult.me().setSuccess(false).setMessage("用户或者密码不正确!");
            }
        }else {
            //没有用户就创建新的用户    获取id绑定微信的user_id
            User newUser = new User();
            newUser.setUsername(username);
            //随机生成一个盐值
            String salt = StrUtils.getComplexRandomString(32);
            newUser.setPassword(MD5Utils.encrypByMd5(password+salt));
            newUser.setSalt(salt);
            //激活
            newUser.setState(1);
            newUser.setCreatetime(new Date());
            userMapper.save(newUser);
            user=newUser;
        }
        //绑定用户
        weChatUser.setUser_id(user.getId());
        weChatUserService.save(weChatUser);
        //免密登录
        //生成一个uToken
        String uToken = UUID.randomUUID().toString();
        //将令牌和用户信息带到前台去和存到redis
        RedisUtils.INSTANCE.set(uToken,JSONObject.toJSONString(user),30*60);
        Map<String,Object> map=new HashMap<>();
        map.put("uToken",uToken);
        map.put("user",user);
        return AjaxResult.me().setResultObj(map);
    }

    /**
     * 把json字符串转成微信用户
     * @param jsonStr
     * @return
     */
    private WeChatUser JsonStr2WeChatUser(String jsonStr) {
        /**
         * 微信返回的微信用户信息
         */
        WeChatUser weChatUser = new WeChatUser();
        //把jsonStr转换成对象
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        weChatUser.setAddress(jsonObject.getString("country")+jsonObject.getString("province")
                +jsonObject.getString("city"));
        weChatUser.setHeadimgurl(jsonObject.getString("headimgurl"));
        weChatUser.setNickname(jsonObject.getString("nickname"));
        weChatUser.setOpenid(jsonObject.getString("openid"));
        return weChatUser;
    }
  • 登录页面前台
<li><a :href="WechatUrl"><i class="am-icon-weixin am-icon-sm"></i><span>微信登录</span> </a></li>

//绑定的值
			WechatUrl: 'https://open.weixin.qq.com/connect/qrconnect?appid=wxd853562a0548a7d0' +
	'&redirect_uri=http://bugtracker.itsource.cn/callback.html&response_type=code&scope=snsapi_login&state=1#wechat_redirect',

回调页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>回调地址</title>
    <!--引入Vue-->
    <script src="plugins/vue/dist/vue.min.js"></script>
    <!--引入axios-->
    <script src="plugins/axios/dist/axios.min.js"></script>
    <!--给Vue添加属性$http-->
    <!--配置axios全局路径-->
    <script src="js/common.js"></script>
</head>
<body>
    <div id="myDiv">

    </div>

</body>
    <script>
        new Vue({
            el:"#myDiv",
            data:{},
            methods:{


            },
            mounted(){
                let obj = parseUrl2Obj(location.href);
                //封装参数携带给后台处理
                let parms={
                    code:obj.code,
                    binderUrl:"http://bugtracker.itsource.cn/binder.html"
                }
                //发送请求,做微信登录
                this.$http.post("/user/weChat",parms).then(result=>{
                    //使用解析表达式接收值
                    let{message,success,resultObj}=result.data;
                    if(success){
                        //返回成功就把utoken和user存放在localstorage中跳转登录页面
                        //存放utoken
                        localStorage.setItem("uToken",resultObj.uToken);
                        localStorage.setItem("user",resultObj.user);
                        //跳转主页去
                        location.href="/index.html";
                        return;
                    }
                    //不成功就跳转绑定页面
                    if(message=="binder"){
                        //跳转绑定页面   resultObj:后台返回的一个url
                        location.href=resultObj;
                    }
                })
            }

        })
    </script>

</html>

绑定页面

<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">

	<head lang="en">
		<meta charset="UTF-8">
		<title>绑定</title>
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
		<meta name="format-detection" content="telephone=no">
		<meta name="renderer" content="webkit">
		<meta http-equiv="Cache-Control" content="no-siteapp" />

		<link rel="stylesheet" href="../AmazeUI-2.4.2/assets/css/amazeui.css" />
		<link href="../css/dlstyle.css" rel="stylesheet" type="text/css">

		<!--导入vue和axios-->
		<script src="./plugins/vue/dist/vue.min.js"></script>
		<script src="./plugins/axios/dist/axios.js"></script>
		<script src="./js/common.js"></script>
	</head>

	<body>
		<div id="loginPage">
		<div class="login-boxtitle">
			<a href="home.html"><img src="res/static/img/logo.png"></a>
		</div>

		<div class="login-banner">
			<div class="login-main">
				<div class="login-banner-bg"><span></span><img src="../images/big.jpg" /></div>
				<div class="login-box">

							<h3 class="title">绑定用户</h3>

							<div class="clear"></div>
						
						<div class="login-form">
						  <form  method="post">
							   <div class="user-name">
								    <label for="user"><i class="am-icon-user"></i></label>
								    <input type="text" v-model="username" name="username" id="user" placeholder="请输入用户名">
               				  </div>
                			 <div class="user-pass">
								    <label for="password"><i class="am-icon-lock"></i></label>
								    <input type="password" v-model="password" name="" id="password" placeholder="请输入密码">
               				  </div>
             			 </form>
           </div>
            

								<div class="am-cf">
									<input type="button" name="" v-on:click="handleBinder()" value="绑 定" class="am-btn am-btn-primary am-btn-sm">
								</div>


				</div>
			</div>
		</div>


					<div class="footer ">
						<div class="footer-hd ">
							<p>
								<a href="# ">恒望科技</a>
								<b>|</b>
								<a href="# ">商城首页</a>
								<b>|</b>
								<a href="# ">支付宝</a>
								<b>|</b>
								<a href="# ">物流</a>
							</p>
						</div>
						<div class="footer-bd ">
							<p>
								<a href="# ">关于恒望</a>
								<a href="# ">合作伙伴</a>
								<a href="# ">联系我们</a>
								<a href="# ">网站地图</a>
								<em>© 2015-2025 Hengwang.com 版权所有. 更多模板 <a href="http://www.cssmoban.com/" target="_blank" title="模板之家">模板之家</a> - Collect from <a href="http://www.cssmoban.com/" title="网页模板" target="_blank">网页模板</a></em>
							</p>
						</div>
					</div>

		</div>


		<script type="text/javascript">
            new Vue({
                el:"#loginPage",
                data(){
                    return {
						username:'',
						password:'',
                    }
                },
                methods:{

                    handleBinder(){

                        let paramsObj = parseUrl2Obj(location.href);
                        var bindParams = {
                            username: this.username,
                            password: this.password,
							//以下参数从地址栏解析
                            accessToken: paramsObj.access_token,
                            openId: paramsObj.openId

                        };
                        this.$http.post("/user/binder",bindParams).then(result => {
                            //success messaage resultObj
                            //解构表达式
                            let {success,message,resultObj}= result.data;
                            if(!success){
                                alert(message);
                                return;

                            }
                            //提供成功
                            alert("登录成功!");
                            //登录成功 存放token和用户到localstorage
                            localStorage.setItem("uToken",resultObj.uToken)
                            localStorage.setItem("user",resultObj.user)
                            //跳转主页
                            location.href = "/index.html"
                        });

                    }


                }
            });
		</script>
	</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜甜掉在星星上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值