复现双验签
This commit is contained in:
parent
b7239af0e0
commit
43c9890f06
|
@ -1,6 +1,10 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,3 +13,144 @@ type KillaraCustomerTokenModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
TableName string // 表名
|
TableName string // 表名
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InsertToken inserts a new token record
|
||||||
|
// func (m *KillaraCustomerTokenModel) InsertToken(data map[string]interface{}) error {
|
||||||
|
// token, ok := data["token"].(string)
|
||||||
|
// if !ok {
|
||||||
|
// return ErrInvalidTokenValue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// m.DeleteToken(token)
|
||||||
|
|
||||||
|
// customerID, _ := data["customer_id"].(uint64)
|
||||||
|
// platform, _ := data["platform"].(int64)
|
||||||
|
// if customerID != 0 && platform != 0 {
|
||||||
|
// m.db.Where("customer_id = ? AND platform = ?", customerID, platform).Delete(&KillaraCustomerToken{})
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return m.db.Create(&KillaraCustomerToken{
|
||||||
|
// Token: &token,
|
||||||
|
// CustomerId: &customerID,
|
||||||
|
// Data: nilStringPtr(data["data"].(string)),
|
||||||
|
// Expiry: nilTimePtr(time.Unix(int64(data["expiry"].(float64)), 0)),
|
||||||
|
// Platform: platform,
|
||||||
|
// }).Error
|
||||||
|
// }
|
||||||
|
|
||||||
|
// UpdateTokenData updates the data field of a token record
|
||||||
|
func (m *KillaraCustomerTokenModel) UpdateTokenData(token string, data map[string]interface{}) error {
|
||||||
|
dataStr, _ := json.Marshal(data)
|
||||||
|
return m.db.Model(&KillaraCustomerToken{}).Where("token = ?", token).Update("data", string(dataStr)).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTokenExpiry updates the expiry field of a token record
|
||||||
|
func (m *KillaraCustomerTokenModel) UpdateTokenExpiry(token string, expiry int64) error {
|
||||||
|
return m.db.Model(&KillaraCustomerToken{}).Where("token = ?", token).Update("expiry", time.Unix(expiry, 0)).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTokenCustomerID updates the customer_id field of a token record
|
||||||
|
func (m *KillaraCustomerTokenModel) UpdateTokenCustomerID(token string, customerID uint64) error {
|
||||||
|
err := m.db.Model(&KillaraCustomerToken{}).Where("token = ?", token).Update("customer_id", customerID).Error
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteToken deletes a token record
|
||||||
|
func (m *KillaraCustomerTokenModel) DeleteToken(token string) error {
|
||||||
|
err := m.db.Where("token = ?", token).Delete(&KillaraCustomerToken{}).Error
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetToken retrieves a token record by token value
|
||||||
|
func (m *KillaraCustomerTokenModel) GetToken(token string) (*KillaraCustomerToken, error) {
|
||||||
|
var record KillaraCustomerToken
|
||||||
|
err := m.db.Where("token = ?", token).First(&record).Error
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return &record, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckToken checks if a token is valid
|
||||||
|
// func (m *KillaraCustomerTokenModel) CheckToken(token string) (*KillaraCustomerToken, error) {
|
||||||
|
// var record KillaraCustomerToken
|
||||||
|
// err := m.db.Where("token = ?", token).First(&record).Error
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if record.Expiry == nil || record.Expiry.Before(time.Now()) {
|
||||||
|
// m.DeleteToken(token)
|
||||||
|
// return nil, ErrTokenExpired
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return &record, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ClearDuplicateToken clears duplicate tokens for a customer_id
|
||||||
|
func (m *KillaraCustomerTokenModel) ClearDuplicateToken(customerID uint64, currentToken string, platform int64) error {
|
||||||
|
tokens := []KillaraCustomerToken{}
|
||||||
|
err := m.db.Where("customer_id = ? AND platform = ?", customerID, platform).Find(&tokens).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, token := range tokens {
|
||||||
|
if *token.Token != currentToken {
|
||||||
|
m.UpdateTokenCustomerID(*token.Token, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTokenByCustomerID retrieves the token value for a customer_id
|
||||||
|
func (m *KillaraCustomerTokenModel) GetTokenByCustomerID(customerID uint64) (string, error) {
|
||||||
|
var record KillaraCustomerToken
|
||||||
|
err := m.db.Select("token").Where("customer_id = ?", customerID).First(&record).Error
|
||||||
|
return *record.Token, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTokenDataByCustomerID retrieves the token data for a customer_id
|
||||||
|
func (m *KillaraCustomerTokenModel) GetTokenDataByCustomerID(customerID uint64) (map[string]interface{}, error) {
|
||||||
|
var record KillaraCustomerToken
|
||||||
|
err := m.db.Select("data").Where("customer_id = ?", customerID).First(&record).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var data map[string]interface{}
|
||||||
|
if record.Data != nil {
|
||||||
|
err = json.Unmarshal([]byte(*record.Data), &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func nilStringPtr(s string) *string {
|
||||||
|
if s == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
func nilTimePtr(t time.Time) *time.Time {
|
||||||
|
if t.IsZero() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &t
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidTokenValue = errors.New("invalid token value")
|
||||||
|
ErrTokenExpired = errors.New("token has expired")
|
||||||
|
)
|
||||||
|
|
197
php_model/Token.php
Normal file
197
php_model/Token.php
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token类存储APP和微信小程序用户登录产生的数据,并负责较验用户的状态。
|
||||||
|
*
|
||||||
|
* @author Evan
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Model_Customer_Token extends \application\Model\Base\BaseModel
|
||||||
|
{
|
||||||
|
private $_customerTokenTable;
|
||||||
|
private $_redisKey = 'token_';
|
||||||
|
|
||||||
|
public $db;
|
||||||
|
public $redis;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->db = \system\engine\Registry::get('db');
|
||||||
|
|
||||||
|
// $this->redis = \system\engine\Registry::get('redis');
|
||||||
|
|
||||||
|
$this->redis = false;
|
||||||
|
|
||||||
|
$config = \system\engine\Registry::get('config');
|
||||||
|
|
||||||
|
$this->tableFullName = $this->_customerTokenTable = $config->database->prefix
|
||||||
|
. 'customer_token';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除指定的登录数据
|
||||||
|
*
|
||||||
|
* @param Array $data <p>登录认证数据</p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function insertToken($data)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->deleteToken($data['token']);
|
||||||
|
|
||||||
|
if (!empty($data['customer_id']) && !empty($data['platform'])) {
|
||||||
|
$this->db->query('DELETE FROM ' . $this->_customerTokenTable . ' WHERE customer_id = '
|
||||||
|
. $this->db->quote($data['customer_id']) . ' AND platform = ' . $this->db->quote($data['platform']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->insert($this->_customerTokenTable, $data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新指定的登录数据
|
||||||
|
*
|
||||||
|
* @param String $token <p>用户登录时生成的token字符串</p>
|
||||||
|
* @param Array $data <p>其它需要记录的数据</p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function updateTokenData($token, $data = array())
|
||||||
|
{
|
||||||
|
|
||||||
|
$where = $this->db->quoteInto('token = ?', $token);
|
||||||
|
|
||||||
|
$this->db->update($this->_customerTokenTable, array(
|
||||||
|
'data' => json_encode($data)
|
||||||
|
), $where);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新登录数据的生命期
|
||||||
|
*
|
||||||
|
* @param String $token <p>用户登录时生成的token字符串</p>
|
||||||
|
* @param Int $expiry <p>过期时间,Unix时间戳</p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function updateTokenExpiry($token, $expiry)
|
||||||
|
{
|
||||||
|
|
||||||
|
$where = $this->db->quoteInto('token = ?', $token);
|
||||||
|
|
||||||
|
$this->db->update($this->_customerTokenTable, array(
|
||||||
|
'expiry' => $expiry
|
||||||
|
), $where);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新登录数据的会员ID
|
||||||
|
*
|
||||||
|
* @param String $token <p>用户登录时生成的token字符串</p>
|
||||||
|
* @param Int $customer_id <p>已登录会员的ID</p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function updateTokenCustomerId($token, $customer_id)
|
||||||
|
{
|
||||||
|
|
||||||
|
$where = $this->db->quoteInto('token = ?', $token);
|
||||||
|
|
||||||
|
$this->db->update($this->_customerTokenTable, array(
|
||||||
|
'customer_id' => $customer_id
|
||||||
|
), $where);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除指定的登录数据
|
||||||
|
*
|
||||||
|
* @param String $token <p>用户登录时生成的token字符串</p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function deleteToken($token)
|
||||||
|
{
|
||||||
|
|
||||||
|
$where = $this->db->quoteInto('token = ?', $token);
|
||||||
|
|
||||||
|
$this->db->delete($this->_customerTokenTable, $where);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*获取用户的登录数据
|
||||||
|
*
|
||||||
|
* @param String $token <p>用户登录时生成的token字符串</p>
|
||||||
|
*
|
||||||
|
* @return Array 一个包含登录数据的数组
|
||||||
|
*/
|
||||||
|
public function getToken($token)
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->db->fetchRow('SELECT * FROM ' . $this->_customerTokenTable
|
||||||
|
. ' WHERE token = ' . $this->db->quote($token));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 较验Token是否有效
|
||||||
|
*
|
||||||
|
* @param String $token <p>用户登录时生成的token字符串</p>
|
||||||
|
*
|
||||||
|
* @return Mix 返回一组会员数据代表验证通过,<b>FALSE</b>代表验证不通过。
|
||||||
|
*/
|
||||||
|
public function checkToken($token)
|
||||||
|
{
|
||||||
|
|
||||||
|
$result = $this->db->fetchRow('SELECT * FROM ' . $this->_customerTokenTable
|
||||||
|
. ' WHERE token = ' . $this->db->quote($token));
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
if ($result['expiry'] > time()) {
|
||||||
|
return $result;
|
||||||
|
} else {
|
||||||
|
$this->deleteToken($token);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*获取用户的登录数据
|
||||||
|
*
|
||||||
|
* @param String $customer_id <p>用户ID</p>
|
||||||
|
* @param String $current_token <p>用户当前有效的token字符串</p>
|
||||||
|
* @param String $platform <p>登录平台ID</p>
|
||||||
|
* @return Boolean 一个包含登录数据的数组
|
||||||
|
*/
|
||||||
|
public function clearDuplicateToken($customer_id, $current_token, $platform = 1)
|
||||||
|
{
|
||||||
|
$results = $this->db->fetchAll('SELECT * FROM ' . $this->_customerTokenTable
|
||||||
|
. ' WHERE customer_id = ' . $this->db->quote($customer_id) . 'AND platform = ' . $this->db->quote($platform));
|
||||||
|
|
||||||
|
foreach ($results as $result) {
|
||||||
|
if ($result['token'] != $current_token) {
|
||||||
|
$this->updateTokenCustomerId($result['token'], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenByCustomerId($customer_id)
|
||||||
|
{
|
||||||
|
return $this->db->fetchOne('SELECT token FROM ' . $this->_customerTokenTable
|
||||||
|
. ' WHERE customer_id = ' . $this->db->quote($customer_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTokenDataByCustomerId($customer_id)
|
||||||
|
{
|
||||||
|
$token_data = $this->db->fetchOne('SELECT data FROM ' . $this->_customerTokenTable
|
||||||
|
. ' WHERE customer_id = ' . $this->db->quote($customer_id));
|
||||||
|
|
||||||
|
return json_decode($token_data, true);
|
||||||
|
}
|
||||||
|
}
|
30
test/password_test.go
Normal file
30
test/password_test.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package vertmore_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/iapologizewhenimwrong/Vestmore_GO/utils/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPassword(t *testing.T) {
|
||||||
|
|
||||||
|
// customer := map[string]string{
|
||||||
|
// "password": "486790f71aea661645b38e94c2734e454dd73a4d",
|
||||||
|
// "salt": "b83192106fa45fef0d914c579848ebea",
|
||||||
|
// "random_password": "709889",
|
||||||
|
// }
|
||||||
|
// password := "6601502.."
|
||||||
|
password := "709889"
|
||||||
|
pwdhash := fmt.Sprintf("%x", sha1.Sum([]byte(password)))
|
||||||
|
|
||||||
|
log.Println()
|
||||||
|
|
||||||
|
if !auth.CheckPassword("486790f71aea661645b38e94c2734e454dd73a4d", "b83192106fa45fef0d914c579848ebea", "709889", pwdhash) {
|
||||||
|
fmt.Println("密码验证失败")
|
||||||
|
} else {
|
||||||
|
fmt.Println("密码验证成功")
|
||||||
|
}
|
||||||
|
}
|
39
utils/auth/check_customer_password.go
Normal file
39
utils/auth/check_customer_password.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/sha1"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// sha1($customer['salt'] . md5($customer['salt'] . $password))
|
||||||
|
func HashPassword(salt, password string) string {
|
||||||
|
saltBytes := []byte(salt)
|
||||||
|
passwordBytes := []byte(password)
|
||||||
|
|
||||||
|
// 计算 md5($customer['salt'] . $password)
|
||||||
|
md5Hash := md5.Sum(append(saltBytes, passwordBytes...))
|
||||||
|
|
||||||
|
// 计算 $customer['salt'] . md5($customer['salt'] . $password)
|
||||||
|
combined := append(saltBytes, []byte(fmt.Sprintf("%x", md5Hash))...)
|
||||||
|
|
||||||
|
// 计算 sha1($customer['salt'] . md5($customer['salt'] . $password))
|
||||||
|
sha1Hash := sha1.Sum(combined)
|
||||||
|
|
||||||
|
return fmt.Sprintf("%x", sha1Hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckPassword(custPassword, salt, randomPassword string, password string) bool {
|
||||||
|
|
||||||
|
if custPassword == HashPassword(salt, password) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证密码规则2
|
||||||
|
if password == fmt.Sprintf("%x", sha1.Sum([]byte(randomPassword))) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果两个条件都不满足,则返回false
|
||||||
|
return false
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user