Пример #1
0
// 认证成功后创建 token 和 session
func authSuccess(ctx *gin.Context, authType string, user *model.User) {
	sid, err := session.NewSessionId()
	if err != nil {
		glog.Errorln(err)
		ctx.JSON(200, errors.ErrInternalServerError)
		return
	}

	timestamp := time.Now().Unix()
	tk := token.Token{
		SessionId:         sid,
		TokenId:           token.NewTokenId(),
		AuthType:          authType,
		ExpirationAccess:  token.ExpirationAccess(timestamp),
		ExpirationRefresh: token.ExpirationRefresh(timestamp),
	}
	tkEncodedBytes, err := tk.Encode()
	if err != nil {
		glog.Errorln(err)
		ctx.JSON(200, errors.ErrTokenEncodeFailed)
		return
	}

	ss := session.Session{
		TokenSignature: tk.Signatrue,
		UserId:         user.Id,
		PasswordTag:    user.PasswordTag,
	}
	if err = session.Add(sid, &ss); err != nil {
		glog.Errorln(err)
		ctx.JSON(200, errors.ErrInternalServerError)
		return
	}

	resp := struct {
		*errors.Error
		Token string `json:"token"`
	}{
		Error: errors.ErrOK,
		Token: string(tkEncodedBytes),
	}
	ctx.JSON(200, &resp)
	return
}
Пример #2
0
// 微信 oauth2 认证
//  需要提供 code, state 参数.
func AuthHandler(ctx *gin.Context) {
	// MustAuthHandler(ctx)
	queryValues := ctx.Request.URL.Query()
	code := queryValues.Get("code")
	if code == "" {
		ctx.JSON(200, errors.ErrBadRequest)
		return
	}
	state := queryValues.Get("state")
	if state == "" {
		ctx.JSON(200, errors.ErrBadRequest)
		return
	}

	ss := ctx.MustGet("sso_session").(*session.Session)

	// 比较 state 是否一致
	if !security.SecureCompareString(state, ss.OAuth2State) {
		ctx.JSON(200, errors.ErrOAuthStateMismatch)
		return
	}

	oauth2Client := oauth2.Client{
		Config: oauth2Config,
	}
	oauth2Token, err := oauth2Client.Exchange(code)
	if err != nil {
		glog.Errorln(err)
		ctx.JSON(200, errors.ErrInternalServerError)
		return
	}
	if oauth2Token.UnionId == "" {
		glog.Errorln("unionid is empty")
		ctx.JSON(200, errors.ErrInternalServerError)
		return
	}

	timestamp := time.Now().Unix()
	user, err := model.GetByWechat(oauth2Token.UnionId)
	switch err {
	default:
		glog.Errorln(err)
		ctx.JSON(200, errors.ErrInternalServerError)
		return
	case model.ErrNotFound:
		var oauth2UserInfo openOAuth2.UserInfo
		if err = oauth2Client.GetUserInfo(&oauth2UserInfo, ""); err != nil {
			glog.Errorln(err)
			ctx.JSON(200, errors.ErrInternalServerError)
			return
		}

		user, err = model.AddByWechat(oauth2Token.UnionId, oauth2UserInfo.Nickname, timestamp)
		if err != nil {
			glog.Errorln(err)
			ctx.JSON(200, errors.ErrInternalServerError)
			return
		}
		fallthrough
	case nil:
		sid, err := session.NewSessionId()
		if err != nil {
			glog.Errorln(err)
			ctx.JSON(200, errors.ErrInternalServerError)
			return
		}

		tk2 := token.Token{
			SessionId:         sid,
			TokenId:           token.NewTokenId(),
			AuthType:          token.AuthTypeOAuthWechat,
			ExpirationAccess:  token.ExpirationAccess(timestamp),
			ExpirationRefresh: token.ExpirationRefresh(timestamp),
		}
		tk2EncodedBytes, err := tk2.Encode()
		if err != nil {
			glog.Errorln(err)
			ctx.JSON(200, errors.ErrTokenEncodeFailed)
			return
		}

		ss2 := session.Session{
			TokenSignature: tk2.Signatrue,
			UserId:         user.Id,
			PasswordTag:    user.PasswordTag,
		}
		if err = session.Add(sid, &ss2); err != nil {
			glog.Errorln(err)
			ctx.JSON(200, errors.ErrInternalServerError)
			return
		}

		resp := struct {
			*errors.Error
			Token string `json:"token"`
		}{
			Error: errors.ErrOK,
			Token: string(tk2EncodedBytes),
		}
		ctx.JSON(200, &resp)
		return
	}
}