Maison >développement back-end >Problème PHP >Comment définir un jeton d'autorisation en php

Comment définir un jeton d'autorisation en php

藏色散人
藏色散人original
2020-08-20 10:13:002665parcourir

Comment définir le jeton en PHP : 1. Définir le chemin de routage pour obtenir le jeton ; 2. Établir la couche Service ; 3. Utiliser la classe UserToken pour gérer l'ensemble de la logique ; la couche Modèle ; 5. Vérifier Créer les méthodes de vérification et la gestion des exceptions correspondantes dans la classe de gestionnaire et la classe d'exception.

Comment définir un jeton d'autorisation en php

Recommandé : "Tutoriel vidéo PHP"

PHP_Set Permission Token Token

L'interface API back-end que nous développons aura des exigences d'autorisation pour les visiteurs. Par exemple, certaines interfaces contenant des informations privées exigent que le visiteur transmette un jeton qui lui a été délivré à l'avance lors de la demande de l'interface.

C'est comme un jeton, nous le "passerons" seulement si le visiteur le montre.

Ce qui suit est un enregistrement des idées d'écriture de code pour les jetons d'autorisation.


1. Aperçu du processus

  • Définir le chemin de routage pour obtenir le jeton et accepter le paramètre de code (source du code : serveur WeChat, le système de connexion est basé sur le système WeChat)

  • Établissez la couche Service et créez la classe de base Token et la classe UserToken dans cette couche

  • La classe UserToken gère toute la logique : Génération et retour de jetons

  • Créer une classe User dans la couche Modèle, qui est responsable de la lecture et de l'écriture des tables de données utilisateur, et peut être appelée par UserToken dans la couche Service .

  • Dans la classe de validation et la classe d'exception Créez les méthodes de vérification correspondantes et la gestion des exceptions

  • Contrôleur->Couche de service->Couche de modèle. renvoie la valeur à la couche Service->La couche Service renvoie la valeur au contrôleur, l'ensemble du processus Terminer l'écriture du jeton

2. Instructions spécifiques

Définissez d'abord le routage path :

Route::post(
    'api/:version/token/user',
    'api/:version.Token/getToken'
);

Créez ensuite le contrôleur Token et définissez la route correspondante La méthode getToken du chemin :

public function getToken($code='') {
        (new TokenGet())->goCheck($code); // 验证器
        $token = (new UserToken($code))->get();
        return [
            'token' => $token
        ];
    }

Avant d'appeler la couche Service, vous devez vérifier les paramètres passés, donc le TokenGet le validateur est défini :

class TokenGet extends BaseValidate
{
    protected $rule = [
      'code' => 'require|isNotEmpty'
    ];

    protected $message = [
        'code' => '需要code才能获得Token!'
    ];
 }

Retournez au contrôleur de jeton, et une fois la vérification réussie, nous appelons la classe UserToken définie par la couche Service :

$token = (new UserToken($code))->get();复制代码

Nous discutons ici de la couche Service et du modèle couche. Notre compréhension générale est que la couche Service est une encapsulation abstraite basée sur la couche Modèle.

  • La couche Modèle est uniquement responsable du fonctionnement de la base de données et de son renvoi à la couche Service
  • Ensuite, la couche Service traite la logique métier et enfin la renvoie à la couche Contrôleur

Mais je pense que pour les petits projets, Service est en fait au même niveau que Modèle, car certaines interfaces simples peuvent être directement connectées au Contrôleur via la couche Modèle. Seules les interfaces relativement complexes, telles que les autorisations utilisateur, peut séparer différentes fonctions via le code de la couche Service.

Ce type de traitement est plus flexible. Il existe un grand nombre d'interfaces très simples et il n'est pas nécessaire de passer par la couche Service une seule fois. Cela ressemble plus à des mouvements et n'a aucun sens.

Retour à l'écriture du code de la couche Service. Puisqu'il existe différents types de Token, nous créons d'abord une classe de base Token, qui contient quelques méthodes courantes. Il y a ensuite la préparation de la classe UserToken qui renvoie le token au visiteur.

Comme il est basé sur WeChat, nous avons besoin de trois informations : code, appid, appsecret, puis attribuons une valeur initiale à la classe UserToken via le constructeur :

function __construct($code) {
    $this->code = $code;
    $this->wxAppID = config('wx.app_id');
    $this->wxAppSecret = config('wx.app_secret');
    $this->wxLoginUrl = sprintf(
        config('wx.login_url'),
        $this->wxAppID, $this->wxAppSecret, $this->code
    );
    }

Ensuite, mettez-les Trois dans La position du paramètre de l'interface fournie par WeChat est d'obtenir une URL complète côté serveur WeChat et de demander l'openid dont nous avons besoin.

Ensuite, l'étape d'envoi d'une requête réseau est ignorée ici. Le serveur WeChat renverra un objet contenant openid. Après avoir jugé que la valeur de cet objet est OK, nous lançons le processus de génération d'un token. Créez la fonction grantToken() :

private function grantToken($openidObj) {

        // 取出openid
        $openid = $openidObj['openid'];
        
        // 通过Model层调用数据库,检查openid是否已经存在
        $user = UserModel::getByOpenID($openid);
        
        // 如果存在,不处理,反之则新增一条user记录
        if ($user) {
            $uid = $user->id;
        } else {
            // 不存在,生成一条数据,具体方法略过
            $uid = $this->newUser($openid); 
        }
        
        // 生成令牌,写入缓存(具体方法见下面的定义)
        $cachedValue = $this->prepareCacheValue($openidObj, $uid);
        $token = $this->saveToCache($cachedValue);
        
        // 令牌返回到调用者端
        return $token;
}

private function prepareCacheValue($openidObj, $uid) {
    $cachedValue = $openidObj;
    $cachedValue['uid'] = $uid;
    $cachedValue['scope'] = 16; // 权限值,自己定义
    return $cachedValue;
}
    
private function saveToCache($cachedValue) {
    $key = self::generateToken(); // 生成令牌的方法
    $value = json_encode($cachedValue);
    $tokenExpire = config('setting.token_expire'); // 设定的过期时间

    $request = cache($key, $value, $tokenExpire);
        if (!$request) {
            throw new TokenException([
            'msg' => '服务器缓存异常',
            'errorCode' => 10005
        ]);
    }
    return $key; // 返回令牌:token
}

Comme vous pouvez le voir, le Le processus principal est :

  • Obtenir l'openid
  • Voir la base de données et vérifier si l'openid existe déjà
  • S'il existe, ne le traitez pas, sinon ajoutez un nouvel enregistrement utilisateur
  • Générer un jeton, préparer les données du cache, écrire dans le cache
  • Retourner le jeton au client

generateToken()Cette méthode est définie en détail comme suit :

public static function generateToken() {
    $randomChars = getRandomChars(32); // 32个字符组成一组随机字符串
    $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];  
    $salt = config('security.token_salt'); // salt 盐
    // 拼接三组字符串,进行MD5加密,然后返回
    return md5($randomChars.$timestamp.$salt);
}
    
function getRandomChars($length) {
    $str = null;
    $strPoll = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $max = strlen($strPoll) - 1;

    for ($i = 0; $i < $length; $i++) {
        $str .= $strPoll[rand(0, $max)];
    }
    return $str;
}

Sa fonction principale est sans aucun doute de générer le token dont nous avons besoin - Token string. Il convient de mentionner que, comme generateToken() est également utilisé dans d'autres types de jetons, il est placé dans la classe de base des jetons.

À ce stade, il vous suffit de renvoyer le jeton généré au contrôleur.

3. Résumé

L'écriture de jetons implique de nombreux processus Afin d'éviter toute confusion, assurez-vous de définir les codes responsables des différentes tâches selon différentes méthodes. Comme le montre la méthode grantToken() dans l'exemple ci-dessus, il s'agit d'une méthode de base qui inclut tous les processus, mais différents processus spécifiques sont définis dans d'autres méthodes puis fournis à l'appel de méthode grantToken().

Après avoir fait cela grantToken() la méthode est toujours facile à lire même si elle inclut tous les processus.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn