我刚刚创建了Vue + Laravel SPA登录,但我不确定它是否足够安全。我是VUE新手:)
我使用的是JWT Auth。当用户输入凭据并提交表单时,Laravel端的Auth将返回用户模型和令牌。此用户存储在本地存储中。在我的Vue路由器中,我创建了运行beforeEach视图更改的中间件。这工作正常,但数据库中没有与此用户相关的实际令牌。当我手动更改存储中的token时,我仍然在传递中间件,因为token不再被检查。它只是检查本地存储中是否存在...我是否应该将令牌存储在数据库中,并在每次视图更改时检查它?或者...??
发布于 2019-05-27 02:03:53
听起来不像是安全的,不:)
我从来没有使用过Laravel,所以我不能具体讨论它,但我可以解释这个过程是如何工作的。
在你的服务器中,你应该有一个中间件或者某种逻辑来读取令牌并验证它的完整性。令牌本身只是一个包含三个组件的Base64字符串
如果您有令牌,则很容易读取有效负载,因为它只是Base64字符串。所以仅仅阅读它是不够的,你需要确保签名是正确的。
当您创建一个JWT令牌时,当您的服务器有一个请求时,您可以使用一个秘密来执行此操作。服务器应验证签名以确保这是有效的令牌。如果你没有这个秘密,你就不能验证签名。只有你才应该知道这个秘密。
这会阻止“我作为攻击者”发送带有虚假负载的令牌。通过验证签名,您可以确保这是您创建的令牌,而不是我发送到您网站的某个假令牌。
您也不应该将该令牌存储在本地存储中。本地存储不应该包含令牌或密码之类的信息,因为它只是一个字典/映射,每个人都可以访问。所以我可以创建一个读取本地存储的网站,获取你创建的令牌,因为这是你的具有正确签名的令牌,所以我现在可以向你的网站发出请求。
我建议将JWT令牌存储在https上的httpOnly cookie中(在大多数环境中,safe: true选项)。浏览器无法读取httpOnly cookies,只能读取服务器。
当从VueJS应用程序向服务器发出请求时,比如保存博客文章,服务器应该
例如
methods: {
saveBlogPost() {
axios.post('/api/save', {
title: 'My blog title'
userId: 'bergur'
})
}
}
您的服务器永远不应该、永远不应该读取从VueJS应用程序发送的userId。JWT中间件应该检查JWT,验证其完整性,然后使用来自有效负载的信息。
编辑:我回复了一篇关于保护VueJS应用程序的类似帖子。你可以在这里找到它:VueJS Secure with Auth0 - How is it secure?
基本上:将信息存储在客户端是很好的,这有助于使用户界面变得有意义,但在执行实际工作时,如保存到数据库中或获取一些私有数据,服务器应该始终验证用户。
发布于 2020-06-12 00:43:01
保护你的服务器端路由是很重要的。我使用的解决方案是使用Laravel
中的php jwt库lcobucci/jwt
。
我将解释如何使用默认且更简单的方法JWT secret策略,而不是私钥/公钥策略(如RSA)。
无论您使用的是哪种框架,JWT
身份验证的步骤都是相同的:
JWT令牌的响应发送,并将其添加到标头以供将来请求使用。<
一个简单的服务器端实现将包括
为传入请求创建验证令牌环境variable
对于这些步骤,请创建一个JWT_SECRET
环境变量。这将是一个很大的随机字符串。您可以使用任何random string generator for this。示例:
JWT_SECRET=bX7fsuHzOksB27Pwh31qmazMsalw4bchu7Ft1X4PMOhO23Zq8nwBKA0FZQOK
创建接口sign-in
路由Route::post('authenticate', 'AuthenticateController@signIn');
app/Http/Controllers/AuthenticateController.php
<?php
namespace App\Http\Controllers;
use App\Services\JWTService;
class AuthenticateController extends Controller
{
protected $jwt;
public function __construct(JWTService $jwt)
{
$this->jwt = $jwt;
}
public function signIn(Request $request){
$token = $this->jwt->createToken();
$response = response()->json([
'message' => StatusCode::$texts[StatusCode::HTTP_OK],
'data' => [ 'token' => (string)$token]
], StatusCode::HTTP_OK);
return $response;
}
}
app/Services/JWTService.php
<?php
namespace App\Services;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Token;
class JWTService
{
public function createToken($privilege = 'externalUser'){
// eval(\Psy\sh());
$signer = new Sha256();
$key = new Key(env('JWT_SECRET')); // vindo null
$time = time();
$token = (new Builder())->issuedBy($privilege)->expiresAt($time + 3600)->getToken($signer, $key);
//->withClaim('uid', 1) // Configures a new claim, called "uid"
return $token;
}
public function parseString($bearerToken) : Token {
return (new Parser())->parse($bearerToken);
}
public function verify($token){
$signer = new Sha256();
$key = new Key(env('JWT_SECRET'));
if(!$token->verify($signer, $key))
abort(401, 'Unauthorized access.');
return true;
}
}
要保护您的路由,请为所有传入请求(登录除外)添加一个中间件。使用jwt声明的授权逻辑将由您决定。
<?php
namespace App\Http\Middleware;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use OutOfBoundsException;
use BadMethodCallException;
use Closure;
class Authorization
{
public function handle($request, Closure $next)
{
try {
$bearerToken = $request->bearerToken();
if(!isset($bearerToken))
abort(401, 'Unauthorized access.');
$token = (new Parser())->parse($bearerToken); // Parses from a string
$signer = new Sha256();
$key = new Key(env('JWT_SECRET'));
if(!$token->verify($signer, $key))
abort(401, 'Unauthorized access.');
return $next($request);
} catch(OutOfBoundsException $e){
abort(401, 'Requested data is not configured.');
} catch(BadMethodCallException $e){
abort(403, 'Token not signed.');
}
}
// $token->getHeaders(); // Retrieves the token header
// $token->getClaims(); // Retrieves the token claims
// $token->getClaim('iss');
// $token->getClaim('exp');
}
将您的中间件添加到kernel.php
protected $routeMiddleware = [
...
'tokenAuth' => \App\Http\Middleware\Authorization::class
];
这样,您就可以通过以下方式将您的中间件添加到routes/api.php
:
Route::group(['middleware' => 'tokenAuth'], function(){
Route::resource('user', 'UserController');
Route::resource('Foo', 'FooController');
}
我强烈推荐阅读Laravel docs和lcobucci/jwt,以更好地理解这些步骤,以及如何使用jwt claims
和Laravel
内置工具实现安全和良好的解决方案。
https://stackoverflow.com/questions/56315586
复制相似问题