Yii2 基礎版實現 Token 認證 API 服務的完整框架方案

以下是一個基于 Yii2 基礎版實現 Token 認證 API 服務的完整框架方案,包含 JWT 實現和完整代碼:

1. 環境準備

composer create-project --prefer-dist yiisoft/yii2-app-basic yii2-api
cd yii2-api

2. 安裝必要擴展

composer require firebase/php-jwt
composer require yiisoft/yii2-faker

3. 數據庫配置 (config/db.php)

return ['class' => 'yii\db\Connection','dsn' => 'mysql:host=localhost;dbname=yii2_api','username' => 'root','password' => '','charset' => 'utf8',
];

4. 用戶模型 (models/User.php)

<?php
namespace app\models;use Yii;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;class User extends ActiveRecord implements IdentityInterface
{const STATUS_ACTIVE = 10;public static function tableName(){return '{{%user}}';}public function rules(){return [['status', 'default', 'value' => self::STATUS_ACTIVE],['status', 'in', 'range' => [self::STATUS_ACTIVE]],];}// 實現 IdentityInterface 方法public static function findIdentity($id){return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);}public static function findIdentityByAccessToken($token, $type = null){try {$secret = Yii::$app->params['jwtSecret'];$decoded = JWT::decode($token, new Key($secret, 'HS256'));return static::findOne(['id' => $decoded->sub, 'status' => self::STATUS_ACTIVE]);} catch (\Exception $e) {return null;}}public function getId(){return $this->id;}public function getAuthKey(){return null; // 不使用 cookie 登錄}public function validateAuthKey($authKey){return false; // 不使用 cookie 登錄}// 生成 JWT Tokenpublic function generateJwt(){$secret = Yii::$app->params['jwtSecret'];$currentTime = time();$payload = ['iss' => 'yii2-api-server', // 簽發者'aud' => 'api-client',      // 接收方'iat' => $currentTime,      // 簽發時間'exp' => $currentTime + 86400, // 過期時間 (24小時)'sub' => $this->id,         // 用戶ID];return JWT::encode($payload, $secret, 'HS256');}// 驗證密碼public function validatePassword($password){return Yii::$app->security->validatePassword($password, $this->password_hash);}// 設置密碼public function setPassword($password){$this->password_hash = Yii::$app->security->generatePasswordHash($password);}
}

5. 登錄表單模型 (models/LoginForm.php)

<?php
namespace app\models;use yii\base\Model;class LoginForm extends Model
{public $username;public $password;public $rememberMe = true;private $_user;public function rules(){return [[['username', 'password'], 'required'],['rememberMe', 'boolean'],['password', 'validatePassword'],];}public function validatePassword($attribute){if (!$this->hasErrors()) {$user = $this->getUser();if (!$user || !$user->validatePassword($this->password)) {$this->addError($attribute, '用戶名或密碼錯誤');}}}public function login(){if ($this->validate()) {return $this->getUser()->generateJwt();}return false;}protected function getUser(){if ($this->_user === null) {$this->_user = User::findByUsername($this->username);}return $this->_user;}
}

6. API 控制器基類 (controllers/ApiController.php)

<?php
namespace app\controllers;use yii\rest\Controller;
use yii\filters\auth\HttpBearerAuth;
use yii\web\UnauthorizedHttpException;class ApiController extends Controller
{public function behaviors(){$behaviors = parent::behaviors();// 啟用 Bearer Token 認證$behaviors['authenticator'] = ['class' => HttpBearerAuth::className(),'optional' => $this->authOptional(), // 排除不需要認證的方法];return $behaviors;}protected function authOptional(){return [];}// 認證失敗處理public function beforeAction($action){if (!parent::beforeAction($action)) {return false;}if (Yii::$app->user->isGuest && !in_array($action->id, $this->authOptional())) {throw new UnauthorizedHttpException('請提供有效的認證令牌');}return true;}
}

7. 認證控制器 (controllers/AuthController.php)

<?php
namespace app\controllers;use app\models\LoginForm;
use yii\rest\Controller;
use yii\web\ServerErrorHttpException;class AuthController extends Controller
{public function actionLogin(){$model = new LoginForm();$model->load(Yii::$app->request->post(), '');if ($token = $model->login()) {return ['token' => $token];} elseif ($model->hasErrors()) {return $model;} else {throw new ServerErrorHttpException('登錄失敗,請稍后重試');}}
}

8. 受保護 API 示例 (controllers/UserController.php)

<?php
namespace app\controllers;class UserController extends ApiController
{protected function authOptional(){return []; // 所有操作都需要認證}public function actionProfile(){$user = Yii::$app->user->identity;return ['id' => $user->id,'username' => $user->username,'email' => $user->email,'created_at' => date('Y-m-d H:i:s', $user->created_at),];}public function actionSecureData(){return ['message' => '這是受保護的API數據','timestamp' => time(),'user_id' => Yii::$app->user->id];}
}

9. 配置參數 (config/params.php)

return ['adminEmail' => 'admin@example.com','jwtSecret' => 'your-secret-key-here', // 替換為強密鑰
];

10. 配置 URL 規則 (config/web.php)

'urlManager' => ['enablePrettyUrl' => true,'showScriptName' => false,'rules' => ['POST /auth/login' => 'auth/login','GET /user/profile' => 'user/profile','GET /secure-data' => 'user/secure-data',// RESTful API 路由示例['class' => 'yii\rest\UrlRule', 'controller' => 'api'],],
],

11. 數據庫遷移

創建用戶表遷移:

yii migrate/create create_user_table
// migrations/mxxxxxx_xxxxxx_create_user_table.php
public function safeUp()
{$this->createTable('{{%user}}', ['id' => $this->primaryKey(),'username' => $this->string(255)->notNull()->unique(),'email' => $this->string(255)->notNull()->unique(),'password_hash' => $this->string(255)->notNull(),'status' => $this->smallInteger()->notNull()->defaultValue(10),'created_at' => $this->integer()->notNull(),'updated_at' => $this->integer()->notNull(),]);
}public function safeDown()
{$this->dropTable('{{%user}}');
}

運行遷移:

yii migrate/up

12. 測試用戶生成 (commands/SeedController.php)

yii migrate/create create_seed_controller
<?php
namespace app\commands;use yii\console\Controller;
use app\models\User;class SeedController extends Controller
{public function actionIndex(){$user = new User();$user->username = 'testuser';$user->email = 'test@example.com';$user->setPassword('password123');$user->created_at = time();$user->updated_at = time();if ($user->save()) {echo "測試用戶創建成功\n";echo "用戶名: testuser\n";echo "密碼: password123\n";} else {print_r($user->errors);}}
}

運行種子:

yii seed

使用示例

1. 獲取 Token
curl -X POST http://api.example.com/auth/login \-H "Content-Type: application/json" \-d '{"username":"testuser", "password":"password123"}'

響應:

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."}
2. 訪問受保護 API
curl -X GET http://api.example.com/user/profile \-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

響應:

{"id": 1,"username": "testuser","email": "test@example.com","created_at": "2023-05-15 10:30:00"
}

安全增強建議

  1. HTTPS 強制使用

    // config/web.php
    'components' => ['request' => ['cookieValidationKey' => 'your-key','enableCsrfValidation' => false, // API 通常禁用 CSRF'parsers' => ['application/json' => 'yii\web\JsonParser',],],
    ],
    
  2. 速率限制

    // 在控制器中添加
    use yii\filters\RateLimiter;public function behaviors()
    {$behaviors = parent::behaviors();$behaviors['rateLimiter'] = ['class' => RateLimiter::class,];return $behaviors;
    }
    
  3. 刷新令牌機制

    • 實現雙令牌系統(access token + refresh token)
    • access token 設置較短有效期(如 30 分鐘)
    • 使用 refresh token 獲取新 access token
  4. 敏感操作日志

    • 記錄所有關鍵操作(登錄、數據修改等)
    • 包含用戶 ID、IP 地址和時間戳

這個框架提供了完整的 JWT 認證實現,包含了用戶管理、Token 生成與驗證、API 保護等核心功能,可以直接作為基礎進行擴展開發。

通義千問-回答
實操成功
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83977.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83977.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83977.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

主流版本控制工具Git vs Perforce P4:架構模式、性能、大文件管理及分支管理對比詳解

Git和Perforce P4是兩個強大的源代碼管理工具&#xff0c;各有其獨特的功能優勢與適用場景。 本文中&#xff0c;Perforce中國授權合作伙伴-龍智將從架構設計、性能表現、文件管理及分支策略等維度&#xff0c;為您詳細解析兩者的關鍵差異&#xff0c;幫助您根據團隊需求&…

文件系統2(Linux下)

1 掛載分區 文件系統1中已經知道了能夠根據inode號在指定分區找文件了&#xff0c;也已經能根據目錄文件內容&#xff0c;找指定的inode了&#xff0c;在指定的分區內&#xff0c;就可以對文件進行操作了。但是還有幾個問題&#xff0c;那就是inode是不能跨分區的&#xff0c;…

Leetcode-?2537. 統計好子數組的數目?

Problem: 2537. 統計好子數組的數目 思路 滑動窗口 解題過程 思路&#xff1a; 使用滑動窗口來維護子數組&#xff0c;并通過組合計數動態調整滿足條件的數對數目。具體來說&#xff0c;我們維護一個窗口[l,r]&#xff0c;使得窗口內相同元素的對數至少為 k&#xff0c;并計算…

js手寫代碼篇--手寫Object.assign

19、Object.assign 作用&#xff1a; Object.assign的作用是將源對象的所有可枚舉屬性復制到目標對象中。它返回目標對象。 const obj1 { a: 1, b: 2 };const obj2 { b: 3, c: 4 };const obj3 { d: 5 };const target {};Object.assign(target, obj1, obj2, obj3);console…

使用 C/C++ 和 OpenCV 構建智能停車場視覺管理系統

使用 C 和 OpenCV 構建智能停車場視覺管理系統 本文將詳細介紹如何利用 C 和 OpenCV 庫&#xff0c;從零開始創建一個智能停車場管理系統。該系統通過攝像頭捕捉的畫面&#xff0c;能自動完成兩項核心任務&#xff1a; 車位識別&#xff1a;通過檢測地面上的黃色停車線&#…

服務器靜態ip,網關不能占用*.*.*.1

網關不能占用*.*.*.1.1 通常用于運行關鍵服務&#xff08;如DHCP、NAT、DNS代理&#xff09;&#xff0c;.1 是網絡世界的"VIP包廂"&#xff0c;普通用戶強闖只會被"請出"。

自然語言處理【NLP】—— CBOW模型

文章目錄 引言一、CBOW模型概述1.1 什么是CBOW模型1.2 CBOW vs Skip-gram 二、CBOW模型原理詳解2.1 模型架構2.2 數學原理2.3 訓練過程 三、CBOW的PyTorch實現四、CBOW模型的應用與優化4.1 典型應用場景4.2 性能優化技巧 五、CBOW的局限性六、結語 引言 在自然語言處理(NLP)領…

為MTK 9300開發板移植Linux系統(以Debian為例)的詳細技術指南

以下是為MTK 9300開發板移植Linux系統(以Debian為例)的詳細技術指南,涵蓋環境搭建、內核移植、驅動適配(攝像頭/顯示器/WiFi)、系統集成與優化。 MTK 9300開發板Linux系統移植全流程指南 1 項目概述 1.1 硬件平臺 SoC:MediaTek MTK9300 (ARMv8-A架構,4Cortex-A78 + 4C…

Java Lambda 表達式與 Stream API 全解析:從基礎到進階

以下是對您博客內容的優化版本&#xff0c;在保留原有核心內容的基礎上&#xff0c;補充了Lambda表達式及Stream API的完整方法體系&#xff0c;并通過結構化排版和擴展說明提升可讀性。 Java Lambda表達式與Stream API全解析&#xff1a;從基礎到進階 一、Lambda表達式與Str…

Let’s Encrypt(樂此加密) 免費SSL證書申請

一、前言 騰訊云、阿里云等平臺都支持免費的SSL證書申請&#xff0c;但只支持單域名SSL證書申請&#xff0c;不支持泛域名證書申請&#xff0c;而且每年只有20張免費證書額度&#xff0c;自2024年4月25日之起免費申請的證書只有3個月有效期。域名比較多的情況下&#xff0c;更新…

SQLite3 性能優化

在嵌入式開發和輕量級應用場景中&#xff0c;SQLite3 作為輕量級數據庫引擎&#xff0c;憑借其無需獨立服務器、部署便捷等特點被廣泛應用。然而&#xff0c;當面對大量數據的高速讀寫需求時&#xff0c;默認配置下的 SQLite3 性能往往難以滿足要求。本文將從數據庫配置調整、W…

零基礎設計模式——行為型模式 - 狀態模式

第四部分&#xff1a;行為型模式 - 狀態模式 (State Pattern) 我們繼續學習行為型模式&#xff0c;接下來是狀態模式。這個模式允許一個對象在其內部狀態改變時改變它的行為&#xff0c;對象看起來就像是改變了它的類。 核心思想&#xff1a;允許一個對象在其內部狀態改變時改…

面向對象面試題集合

前言 記錄面向對象面試題相關內容&#xff0c;方便復習及查漏補缺 題1.簡述面向對象&#xff1f;主要特征是什么&#xff1f; 面向對象編程&#xff08;Object-Oriented Programming&#xff0c;簡稱OOP&#xff09;是一種以“對象”為核心的編程范式&#xff0c;通過將現實…

二十一、【用戶管理與權限 - 篇三】角色管理:前端角色列表與 CRUD 實現

【用戶管理與權限 - 篇三】角色管理:前端角色列表與 CRUD 實現 前言準備工作第一部分:更新 API 服務以包含角色管理第二部分:添加角色管理頁面的路由和側邊欄入口第三部分:實現角色列表頁面第四部分:實現角色表單對話框組件第五部分:全面測試總結前言 一個完善的權限系統…

Objective-c protocol 練習

題目描述&#xff1a; 請使用 Objective-C 中的 protocol 協議機制&#xff0c;實現一個簡易的門禁控制系統。 系統包含兩個類&#xff1a; AccessControlSystem —— 門禁系統&#xff0c;用于執行開門操作&#xff1b;Admin —— 實現權限判斷邏輯的管理員。 要求如下&am…

科技創新賦能產業創新,雙輪驅動助力新疆高質量發展!

在新疆維吾爾自治區成立70周年之際&#xff0c;中國產學研合作促進會于6月14日在烏魯木齊舉辦“天山對話&#xff1a;推動新疆科技創新與產業創新”盛會。多位院士、專家、學者及企業代表齊聚一堂&#xff0c;探尋推動新疆科技創新和產業創新的新路徑、新動能。活動現場&#x…

C#最佳實踐:推薦使用 nameof 而非硬編碼名稱

C#最佳實踐:推薦使用 nameof 而非硬編碼名稱 在 C# 編程領域,代碼的可維護性、健壯性和可讀性是衡量程序質量的重要指標。在日常開發中,我們常常會遇到需要引用類型、成員或變量名稱的場景,比如在拋出異常時指定錯誤相關的變量名、在日志記錄中標記關鍵元素名稱等。傳統的…

vue3 iframe 跨域-通訊

一、基礎嵌套方法 直接在 HTML 中使用 <iframe> 標簽指定 src 屬性&#xff1a; <iframe src"https://目標網址.com" width"800" height"600"></iframe>?限制?&#xff1a;若目標網站設置了 X-Frame-Options 響應頭&#x…

Iceberg與Hive集成深度

一、Iceberg在Hive中的ACID事務實現與實戰 1.1 傳統Hive的事務局限性 Hive原生僅支持非事務表&#xff08;Non-ACID&#xff09;&#xff0c;存在以下痛點&#xff1a; 不支持行級更新/刪除并發寫入時數據一致性無法保證無事務回滾機制歷史版本查詢需手動實現 1.2 Iceberg為…

深入剖析 Celery:分布式異步任務處理的利器

本文在創作過程中借助 AI 工具輔助資料整理與內容優化。圖片來源網絡。 文章目錄 引言一、Celery 概述1.1 Celery 的定義和作用1.2 Celery 的應用場景 二、Celery 架構分析2.1 Celery 的整體架構2.2 消息中間件&#xff08;Broker&#xff09;2.3 任務隊列&#xff08;Task Que…