gin-vue-admin小程序用户token操作(思路记录,不完善)

1 篇文章 0 订阅

说明:自己用的,你复制过去并不能正常使用,仅作为思路,还需继续完善。

gin-vue-admin端

1.路由处router/user_token.go

package router

import (
	"gin-vue-admin/api/v1"
	"github.com/gin-gonic/gin"
)

func InitUserToken(Router *gin.RouterGroup) {
	UserToken := Router.Group("UserToken")
	{
		UserToken.POST("token", v1.GetUserToken)
		UserToken.POST("verify", v1.VerifyToken)
		// UserToken.POST("refresh", v1.TokenRefresh)
		//刷新的不知道哪里一直说invalid,解决不了
	}
}

1.api处 api/v1/user_token.go

package v1

import (
	"fmt"
	"gin-vue-admin/global/response"
	"gin-vue-admin/model"
	// "gin-vue-admin/model/request"
	// resp "gin-vue-admin/model/response"
	"gin-vue-admin/service"
	"github.com/gin-gonic/gin"
	"github.com/medivhzhan/weapp/v2"
	// "github.com/dgrijalva/jwt-go"
	// "github.com/go-redis/redis"
	"gin-vue-admin/middleware"
	"strconv"
	"go.uber.org/zap"
	"gin-vue-admin/global"
	"time"
)

// 获取新的token
func  GetUserToken(c *gin.Context)  {
	// userWxCode:= c.DefaultQuery("code","没有值")
	userWxCode := c.PostForm("code")
	//1.从数据库中获取到小程序的信息
	// var wxMiniPro model.WxMiniPro
	errsql,wxMiniProResult:=service.GetWxMiniProFirst()
	if errsql !=nil{
		//数据库取值错误
		response.FailWithMessage(fmt.Sprintf("小程序信息查询失败,%v", errsql), c)
	}

	// fmt.Printf("查询结果: %#v", wxMiniProResult)

	resWX, err := weapp.Login(wxMiniProResult.WxMiniProAppid, wxMiniProResult.WxMiniProSecret, userWxCode)
	if err != nil {
		fmt.Printf("处理一般错误信息: %#v\n", err)
		// 处理一般错误信息
		return
	}
	if err := resWX.GetResponseError(); err !=nil {
		fmt.Printf("处理微信返回错误信息: %#v\n", err)
		// 处理微信返回错误信息
		return
	}

	//看系统中有没有该用户
	checkErr,checkUserReturn:= service.GetSysUserById(resWX.OpenID)

	if checkErr !=nil{
		//2.利用openid创建系统用户账号
		var commomUserPwd="bunanedu.cn"
		var sysUser model.SysUser
		sysUser = model.SysUser{
			Username:resWX.OpenID, NickName: "微信用户", Password: commomUserPwd, HeaderImg: "", AuthorityId: "888",
			WxUser:model.WxUser{
				WxUserOpenid:resWX.OpenID,
				WxUserSessionkey:resWX.SessionKey,
				WxUserUnionid:resWX.UnionID}}
		errRegister, userReturn := service.Register(sysUser)
		if errRegister !=nil{
			response.FailWithMessage(fmt.Sprintf("创建系统用户失败,%v", errRegister), c)
		}else{
			loginAndTokenNext(c,userReturn)

		}
	}else{
		loginAndTokenNext(c,checkUserReturn)
	}

}

func loginAndTokenNext(c *gin.Context,userReturn model.SysUser){
	var commomUserPwd="bunanedu.cn"
	U := &model.SysUser{Username: userReturn.Username, Password: commomUserPwd}
	if err, user := service.Login(U); err != nil {
		response.FailWithMessage(fmt.Sprintf("用户名密码错误或%v", err), c)
	} else {
	//分配token
	tokenNext(c, *user)
		// wxMiniTokenNext(c, *user)
	}
}

// 验证token是否有效
func VerifyToken(c *gin.Context)  {
	token := c.Request.Header.Get("x-token")
	j := middleware.NewJWT()
	// parseToken 解析token包含的信息
	claims, err := j.ParseToken(token)
	if err != nil {
		if err == middleware.TokenExpired {
			response.Result(response.ERROR, gin.H{
				"reload": true,
			}, "授权已过期", c)
			c.Abort()
			return
		}
		response.Result(response.ERROR, gin.H{
			"reload": true,
		}, err.Error(), c)
		c.Abort()
		return
	}
	if claims.ExpiresAt - time.Now().Unix()<claims.BufferTime {
		claims.ExpiresAt = time.Now().Unix() + 60*60*24*7
		newToken,_ := j.CreateToken(*claims)
		newClaims,_ := j.ParseToken(newToken)
		c.Header("new-token",newToken)
		c.Header("new-expires-at",strconv.FormatInt(newClaims.ExpiresAt,10))
		if global.GVA_CONFIG.System.UseMultipoint {
			err,RedisJwtToken := service.GetRedisJWT(newClaims.Username)
			if err!=nil {
				global.GVA_LOG.Error("get redis jwt failed",  zap.Any("err", err))
			}else{
				service.JsonInBlacklist(model.JwtBlacklist{Jwt: RedisJwtToken})
				//当之前的取成功时才进行拉黑操作
			}
			// 无论如何都要记录当前的活跃状态
			_ = service.SetRedisJWT(newToken,newClaims.Username)
		}
	}
	c.Set("claims", claims)
	c.Next()	
}


//刷新token  因为报错不知道怎么解决
// func TokenRefresh(c *gin.Context)  {
// 	token := c.PostForm("old_token")
// 	fmt.Printf("查询结果: %#v", token)
// 	j := middleware.NewJWT()
// 	newToken,err:= j.RefreshToken(token)
// 	 if err != nil {
// 		response.FailWithMessage(fmt.Sprintf("刷新失败%v", err), c)
// 	} else {
// 		response.OkWithData(gin.H{"token": newToken}, c)
// 	}
// }

小程序端

1.http/http.api.js

let getUserTokenUrl = '/UserToken/token';
let verifyTokenUrl = '/UserToken/verify/';
// let refreshTokenUrl = '/UserToken/refresh/';
const install = (Vue, vm) => {
    let getUserToken = (params = {}) => vm.$u.post(getUserTokenUrl, params);
    let verifyToken = (params = {}) => vm.$u.post(verifyTokenUrl, params);
    // let refreshToken = (params = {}) => vm.$u.post(refreshTokenUrl, params);
    vm.$u.api = {
        getUserToken,
        verifyToken,
        // refreshToken,
    };
}

export default {
    install
}

2.http/http.token.js

import Vue from 'vue'
const has_token = data => {
    // 检查本地是否存有token
    try {
        const lifeData = uni.getStorageSync('lifeData');
        if (lifeData.vuex_token) {
            return true
        } else {
            return false
        }
    } catch (e) {
        return false
    }
}

const login = login => {
    return new Promise(function(resolve, reject) {
        uni.login({
            provider: 'weixin',
            success(res) {
                resolve(res)
            },
            fail(err) {
                reject(err)
            }
        })
    })
}

const get_token = async data => {
    // 网络获取token
    var token = null;
    var code_res = null;
    await login().then(res => {
        code_res = res.code
    })
    Vue.prototype.$u.api.getUserToken({
        "code": code_res
    }).then(res => {
        Vue.prototype.$u.vuex('vuex_token',
            res.data.data.token);
        Vue.prototype.$u.vuex('vuex_user',
            res.data.data.user);
    }).catch(err => {
    });

    // return token == null ? wx.getStorageSync('vuex_token') || '' : token;
}

const check_token = async data => {
    // 检查token是否有效
    const lifeData = uni.getStorageSync('lifeData');
    let access_token = lifeData.vuex_token || '';
    let state;

    await Vue.prototype.$u.api.verifyToken({
        'token': access_token
    }).then((res) => {
        if (res.data.msg=='授权已过期' || res.data.msg=='Token not active yet') {
            state = false;
        } else {
            state = true;
        }
    })
    return state
}

const refresh_token = async data => {
    // 刷新token
    const lifeData = uni.getStorageSync('lifeData');
    let temp_token = lifeData.vuex_token || '';
    let re_token = null;
    let token = null;
    if (temp_token == '') {
        await get_token().then(res => {
           Vue.prototype.$u.vuex('vuex_token',
               res.data.data.token);
            token = res;
        })
    } else {
        await Vue.prototype.$u.api.refreshToken({
            'old_token': temp_token
        }).then((res) => {
            console.log(res)
            if (res.data.msg=='更新失败token is not valid yet') {
                console.log(res.data.msg)
            } else{
                try {
                   Vue.prototype.$u.vuex('vuex_token',
                       res.data.data.token);
                } catch (e) {
                    console.log(e)
                }
            }
            // else if (res.statusCode === 401) {
            //     // refresh token 过期 重新获取
            //     // get_token();
            //     re_token = true;
            // } else {
            //     re_token = false;
            //     console.log(res.data)
            // }
        })
       
        if (re_token == true) {
            await get_token().then(res => {
                Vue.prototype.$u.vuex('vuex_token',
                    res.data.data.token);
                token = res;
            })
        } else if (re_token == false) {
            console.log('出错')
        }
    }
}

module.exports = {
    has_token: has_token,
    get_token: get_token,
    check_token: check_token,
    refresh_token: refresh_token,
}

/*
 * token存取可能存在时差 导致token为空
 */

App.vue中部分使用

import token from 'common/http/http.token.js'
autoLogin() {
    if (!token.has_token()) {
        token.get_token().then(
            res => {
                // this.userInfoInit()
            })
    } else {
        //检查token是否有效
        token.check_token().then(res => {
            if (res) {
                // token 有效
                // this.userInfoInit()
            } else {
                // token 失效 获取新token
                // token.refresh_token().then(res => {
                //     // this.userInfoInit()
                // })
                token.get_token().then(
                    res => {
                        // this.userInfoInit()
                    })
            }
        })
    }

},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值