oracle access manager token,Laravel 自带的 API 守卫驱动 token 使用详解
在Laravel框架中,默认的用户认证守卫有两个,web和api,web守卫默认的驱动是session,而api守卫默认的驱动是token。那么,该如何使用这个token驱动?
寻找 TokenGuard
通过 Auth::guard() 这个方法,可以追溯到 token 驱动对应的类。来看Illuminate\Auth\AuthManager中的代码:
/**
* Attempt to get the guard from the local cache.
*
* @param string $name
* @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
*/
public function guard($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return $this->guards[$name] ?? $this->guards[$name] = $this->resolve($name);
}
/**
* Resolve the given guard.
*
* @param string $name
* @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Auth guard [{$name}] is not defined.");
}
if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($name, $config);
}
$driverMethod = 'create'.ucfirst($config['driver']).'Driver';
if (method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($name, $config);
}
throw new InvalidArgumentException("Auth driver [{$config['driver']}] for guard [{$name}] is not defined.");
}
可以看到,默认情况下就会调用到 createTokenDriver 。来看看这个方法:
public function createTokenDriver($name, $config)
{
// The token guard implements a basic API token based guard implementation
// that takes an API token field from the request and matches it to the
// user in the database or another persistence layer where users are.
$guard = new TokenGuard(
$this->createUserProvider($config['provider'] ?? null),
$this->app['request']
);
$this->app->refresh('request', $guard, 'setRequest');
return $guard;
}
显然,api守卫默认的驱动就是TokenGuard。
解读 TokenGuard
/**
* Create a new authentication guard.
*
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param \Illuminate\Http\Request $request
* @param string $inputKey
* @param string $storageKey
* @return void
*/
public function __construct(UserProvider $provider, Request $request, $inputKey = 'api_token', $storageKey = 'api_token')
{
$this->request = $request;
$this->provider = $provider;
$this->inputKey = $inputKey;
$this->storageKey = $storageKey;
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
// If we've already retrieved the user for the current request we can just
// return it back immediately. We do not want to fetch the user data on
// every call to this method because that would be tremendously slow.
if (! is_null($this->user)) {
return $this->user;
}
$user = null;
$token = $this->getTokenForRequest();
if (! empty($token)) {
$user = $this->provider->retrieveByCredentials(
[$this->storageKey => $token]
);
}
return $this->user = $user;
}
从构造函数和 user() 方法中可以看出,默认使用
['api_token' => $token]
这个数组去获取用户,也就是说,在用户表中我们需要一个字段(默认api_token)去存储标识用户的 token。
开始使用 token 进行api认证
添加数据表字段
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddUsersApiTokenField extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('api_token', 60)->unique()->nullable()->after('password');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('api_token');
});
}
}
创建登录控制器
这里不演示注册之类的,假设我们的 users 表中已经存在用户,先创建一个用于 api 登录的控制器。在每次登录的时候,更新一次用户的 api_token 。这里使用了 ThrottlesLogins ,用来控制登录的尝试次数。
namespace App\Http\Controllers\Api;
use Hash;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Validation\ValidationException;
class LoginController extends Controller
{
use ThrottlesLogins;
/**
* @param Request $request
* @return \Illuminate\Http\Response|void
* @throws ValidationException
*/
public function login(Request $request)
{
$this->validateLogin($request);
if ($this->hasTooManyLoginAttempts($request)) {
return $this->sendLockoutResponse($request);
}
return $this->attempLogin($request);
}
/**
* @param Request $request
*/
public function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required|string',
'password' => 'required|string'
]);
}
/**
* @param Request $request
* @return \Illuminate\Http\Response|void
*/
protected function attempLogin(Request $request)
{
$this->incrementLoginAttempts($request);
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
return $this->sendFailedLoginResponse($request);
}
// 更新 api_key
$api_token = uniqid($user->id);
$user->api_token = $api_token;
$user->save();
return $this->sendLoginResponse($request, $user);
}
/**
* @param Request $request
*/
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
/**
* @param Request $request
* @param User $user
* @return \Illuminate\Http\Response
*/
protected function sendLoginResponse(Request $request, User $user)
{
$this->clearLoginAttempts($request);
return \Response::make([
'user' => $user,
'token' => $user->api_token
]);
}
public function username()
{
return 'email';
}
}
添加登录路由
将 routes\api.php 修改如下:
Route::namespace('Api')->group(function () {
Route::post('login', 'LoginController@login');
}); # 登录路由
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
调试
测试之前先往 users 表中添加几个用户,以下是我的测试数据。
可以看到登录成功并且返回了 token 。
接下去我们使用获取到的 token 请求需要登录的接口,默认有一个,就是/user.
ok~ 已经成功返回了数据,说明登录成功了!
例子中,api_token 是通过 OAuth 2.0 Access Token 的形式传进去的,但这不是唯一的方法,可以查看 TokenGuard 中的 getTokenForRequest 这个方法,它告诉我们可以用四种不同的形式传入 api_token
总结
默认的 api token 认证虽然在文档中没有提及如何使用,但是通过查看代码,也很容易使用。但是,在我们不重写或者扩展 tokenGUard的情况下,api_token 简直就是裸奔,显然不可能就这样应用到项目中去。个人猜测,框架中提供这个功能是为了让我们更好的理解 api 认证的工作原理,方便我们开发自己需要的 guard ,而且官方文档也推荐我们使用 passport 或者 jwt 进行 api 认证。
本文出于个人对默认配置的好奇进而探究之后写下的一片文章,也借鉴了网上的部分文章(忘记查看的文章地址了,也懒得找了),如有理解不到位或者错误的,请!斧!正!
欢迎任何形式转载,记得注明出处哦!
本作品采用《CC 协议》,转载必须注明作者和本文链接
oracle access manager token,Laravel 自带的 API 守卫驱动 token 使用详解相关推荐
- spring boot 集成 Oracle Access Manager(OAM)单点登录
1.介绍 Oracle Access Manager(OAM)是oracle公司开发的身份认证和资源管理解决方案.结合WebGate和OHS可实现系统间单点登录集成. oracle中间件产品可以非常方 ...
- Windows系统里Oracle 11g R2 Client(64bit)的下载与安装(图文详解)
1.全网最详细的Windows系统里Oracle 11g R2 Client(64bit)的下载与安装(图文详解) 方法地址:https://www.cnblogs.com/zlslch/p/9273 ...
- oracle access manager token,AuthenticationManager验证原理
AuthenticationManager相关类图 AuthenticationManager验证过程 AuthenticationManager验证过程涉及到的类和接口较多,我们就从这里开始逐一分析 ...
- oracle home 命令,$ORACLE_HOMEbin目录下所有命令的使用方法及命令详解
求$ORACLE_HOME/bin目录下所有命令的使用方法及命令详解 如题. $ORACLE_HOME/bin目录下有很多命令,那我们平时用到的也不是太多,即使用到的那部分可能用法也不是完全能掌握,所 ...
- 九爷带你了解 nginx 日志配置指令详解
nginx日志配置指令详解 日志对于统计排错来说非常有利的. 本文总结了nginx日志相关的配置如 access_log.log_format.open_log_file_cache.log_not_ ...
- 线性代数带参数的线性方程组的求法示例详解
线性方程组的求法与示例详解 线性方程组 由n个1维未知量,m个方程组成的组合叫做线性方程组. 特别的当方程组右边的值全都是0时叫做齐次线性方程组. 增广矩阵 在系数矩阵的右边添上一列,该列由线性方程组 ...
- oracle不能访问管理页面,无法登录Oracle Access Manager的OAM控制台
登录后我无法访问OAMConsole主页 . OAM安装在Centos 6.4 Server Edition上,我通过FireFox访问控制台 . 我可以毫无问题地访问控制台和企业管理器 . 但是,当 ...
- oracle创建用户、表空间、临时表空间、分配权限步骤详解
首先登陆管理员账号,或者有DBA权限的用户,接下来依次: --查询所有用户 select * from dba_users; --创建新用户 create user gpmgt identified ...
- php manual 反射,Laravel框架源码解析之反射的使用详解
本文实例讲述了Laravel框架源码解析之反射的使用.分享给大家供大家参考,具体如下: 前言 PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法.成员,而反射类则是拆封类中的所有方法.成员 ...
最新文章
- Fastlane实战(一):移动开发自动化之道
- Centos7部署ntp服务器同步时间以及直接将本地时间同步为北京时间
- 探究Facebook相似性搜索工具 faiss的原理
- mui switch 实现方案 让你的html 设计更贴近原生
- 「雕爷学编程」Arduino动手做(38)——joystick双轴摇杆模块
- 【Kafka】kafka AdminClient API
- python字符串转义表
- oracle大数据量迁移,分批量导入样例(fetch...bulk collect)以及forall结合使用
- 无人机探测雷达软硬件解决方案
- ssl2334 铲雪车
- 双android系统pcb整合,基于Android的大屏幕拼接显示系统研究与实现
- 理财项目中宏涌晟五个投资理财基础知识
- python入门和使用
- 网易新闻回答2021:靠差异化内容逆势增长
- AMiner订阅小程序上线,随时随地掌握最新科研成果
- 人机交互技术课程实验报告《社交点评APP》系统移动界面分析报告
- 使用MATLAB计算一幅图像的熵
- python爬取云顶之弈官网排名数据
- APICS与AX的Master Planning(三)---Firm Planned Orders已确认计划订单
- 【概率统计】用正态分布和泊松分布近似表示二项分布