基于 API 调用响应的自定义用户身份验证

编程入门 行业动态 更新时间:2024-10-25 04:26:24
本文介绍了基于 API 调用响应的自定义用户身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

说明:

我现在已经在很多项目中使用 Laravel.在 Laravel 中实现用户认证很简单.现在,我处理的结构有点不同 - 我在本地没有 database 或 users 表.我必须进行 API 调用以查询我需要的内容.

I have been using Laravel for a bunch of project now. Implementing User Authentication is simple in Laravel. Now, the structure that I am dealing with is a little different - I don't have a database or a users table locally. I have to make an API call to query what I need.

我试过了

public function postSignIn(){ $username = strtolower(Input::get('username')); $password_api = VSE::user('password',$username); // abc <----- $password = Input::get('password'); // abc <----- if ( $password == $password_api ) { //Log user in $auth = Auth::attempt(); // Stuck here <---- } if ($auth) { return Redirect::to('/dashboard')->with('success', 'Hi '. $username .' ! You have been successfully logged in.'); } else { return Redirect::to('/')->with('error', 'Username/Password Wrong')->withInput(Request::except('password'))->with('username', $username); } }

更新

我在我的 VSE 类中使用一个简单的 shell_exec 命令连接到 API

I connect to the API using a simple shell_exec command in my VSE class

public static function user($attr, $username) { $data = shell_exec('curl '.env('API_HOST').'vse/accounts'); $raw = json_decode($data,true); $array = $raw['data']; return $array[$attr]; }

我希望我可以在这里向您展示,但它在我本地机器上的 VM 上,所以请留在我这里.基本上,它

I wish I can show that to you here, But it is on the VM on my local machine so please stay with me here. Basically, It

执行

curl 172.16.67.137:1234/vse/accounts <--- 更新

回复

Object data:Array[2] 0:Object DBA:"" account_id:111 account_type:"admin" address1:"111 Park Ave" address2:"Floor 4" address3:"Suite 4011" city:"New York" customer_type:2 display_name:"BobJ" email_address:"bob@xyzcorp" first_name:"Bob" last_name:"Jones" last_updated_utc_in_secs:200200300 middle_names:"X." name_prefix:"Mr" name_suffix:"Jr." nation_code:"USA" non_person_name:false password:"abc" phone1:"212-555-1212" phone2:"" phone3:"" postal_code:"10022" state:"NY" time_zone_offset_from_utc:-5 1:Object DBA:"" account_id:112 account_type:"mbn" address1:"112 Park Ave" address2:"Floor 3" address3:"Suite 3011" city:"New York" customer_type:2 display_name:"TomS" email_address:"tom@xyzcorp" first_name:"Tom" last_name:"Smith" last_updated_utc_in_secs:200200300 middle_names:"Z." name_prefix:"Mr" name_suffix:"Sr." nation_code:"USA" non_person_name:false password:"abd" phone1:"212-555-2323" phone2:"" phone3:"" postal_code:"10022" state:"NY" time_zone_offset_from_utc:-5 message:"Success" status:200

如您所见,Bob 的密码是 abc,而 Tom 的密码是 abd

As you can see the password for Bob is abc and for Tom is abd

推荐答案

按照以下步骤,您可以设置自己的身份验证驱动程序,使用 API 调用处理获取和验证用户凭据:

By following the steps below, you can setup your own authentication driver that handles fetching and validating the user credentials using your API call:

1. 在 app/Auth/ApiUserProvider.php 中创建您自己的自定义用户提供程序,内容如下:

1. Create your own custom user provider in app/Auth/ApiUserProvider.php with the following contents:

namespace AppAuth; use IlluminateContractsAuthUserProvider; use IlluminateContractsAuthAuthenticatable as UserContract; class ApiUserProvider implements UserProvider { /** * Retrieve a user by the given credentials. * * @param array $credentials * @return IlluminateContractsAuthAuthenticatable|null */ public function retrieveByCredentials(array $credentials) { $user = $this->getUserByUsername($credentials['username']); return $this->getApiUser($user); } /** * Retrieve a user by their unique identifier. * * @param mixed $identifier * @return IlluminateContractsAuthAuthenticatable|null */ public function retrieveById($identifier) { $user = $this->getUserById($identifier); return $this->getApiUser($user); } /** * Validate a user against the given credentials. * * @param IlluminateContractsAuthAuthenticatable $user * @param array $credentials * @return bool */ public function validateCredentials(UserContract $user, array $credentials) { return $user->getAuthPassword() == $credentials['password']; } /** * Get the api user. * * @param mixed $user * @return AppAuthApiUser|null */ protected function getApiUser($user) { if ($user !== null) { return new ApiUser($user); } } /** * Get the use details from your API. * * @param string $username * @return array|null */ protected function getUsers() { $ch = curl_init(); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, env('API_HOST') . 'vse/accounts'); $response = curl_exec($ch); $response = json_decode($response, true); curl_close($ch); return $response['data']; } protected function getUserById($id) { $user = []; foreach ($this->getUsers() as $item) { if ($item['account_id'] == $id) { $user = $item; break; } } return $user ?: null; } protected function getUserByUsername($username) { $user = []; foreach ($this->getUsers() as $item) { if ($item['email_address'] == $username) { $user = $item; break; } } return $user ?: null; } // The methods below need to be defined because of the Authenticatable contract // but need no implementation for 'Auth::attempt' to work and can be implemented // if you need their functionality public function retrieveByToken($identifier, $token) { } public function updateRememberToken(UserContract $user, $token) { } }

2. 还要创建一个用户类,它扩展了 app/Auth/ApiUser.php 中认证系统提供的默认 GenericUser以下内容:

2. Also create a user class that extends the default GenericUser offered by the authentication system in app/Auth/ApiUser.php with the following contents:

namespace AppAuth; use IlluminateAuthGenericUser; use IlluminateContractsAuthAuthenticatable as UserContract; class ApiUser extends GenericUser implements UserContract { public function getAuthIdentifier() { return $this->attributes['account_id']; } }

3. 在您的 app/Providers/AuthServiceProvider.php 文件的启动方法中,注册新的驱动程序用户提供程序:

3. In your app/Providers/AuthServiceProvider.php file's boot method, register the new driver user provider:

public function boot(GateContract $gate) { $this->registerPolicies($gate); // The code below sets up the 'api' driver $this->app['auth']->extend('api', function() { return new AppAuthApiUserProvider(); }); }

4. 最后在您的 config/auth.php 文件中将驱动程序设置为您的自定义驱动程序:

4. Finally in your config/auth.php file set the driver to your custom one:

'driver' => 'api',

您现在可以在控制器操作中执行以下操作:

You can now do the following in your controller action:

public function postSignIn() { $username = strtolower(Input::get('username')); $password = Input::get('password'); if (Auth::attempt(['username' => $username, 'password' => $password])) { return Redirect::to('/dashboard')->with('success', 'Hi '. $username .'! You have been successfully logged in.'); } else { return Redirect::to('/')->with('error', 'Username/Password Wrong')->withInput(Request::except('password'))->with('username', $username); } }

在成功登录后调用 Auth::user() 以获取用户详细信息,将返回一个 ApiUser 实例,其中包含从远程 API 获取的属性,并且看起来有些像像这样:

Calling Auth::user() to get user details after a successful login, will return an ApiUser instance containing the attributes fetched from the remote API and would look something like this:

ApiUser {#143 ▼ #attributes: array:10 [▼ "DBA" => "" "account_id" => 111 "account_type" => "admin" "display_name" => "BobJ" "email_address" => "bob@xyzcorp" "first_name" => "Bob" "last_name" => "Jones" "password" => "abc" "message" => "Success" "status" => 200 ] }

由于您尚未发布在 API 中没有匹配用户电子邮件时获得的响应示例,因此我在 getUserDetails 方法中设置了条件,以确定没有如果响应不包含 data 属性或 data 属性为空,则匹配并返回 null.您可以根据需要更改该条件.

Since you haven't posted a sample of the response that you get when there's no match in the API for the user email, I setup the condition in the getUserDetails method, to determine that there's no match and return null if the response doesn't contain a data property or if the data property is empty. You can change that condition according to your needs.

上面的代码使用模拟响应进行了测试,该响应返回您在问题中发布的数据结构,并且运行良好.

The code above was tested using a mocked response that returns the data structure you posted in your question and it works very well.

最后一点:您应该强烈考虑修改 API 以尽快处理用户身份验证(可能使用 Oauth 实现),因为将密码发送过来(甚至更令人担忧的是作为纯文本)不是你想要推迟做的事情.

As a final note: you should strongly consider modifying the API to handle the user authentication sooner rather than later (perhaps using a Oauth implementation), because having the password sent over (and even more worryingly as plain text) is not something you want to postpone doing.

更多推荐

基于 API 调用响应的自定义用户身份验证

本文发布于:2023-11-07 17:43:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1567036.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   身份验证   用户   API

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!