如何在没有数据库的情况下验证令牌? [英] How to validate a token without a database?

查看:68
本文介绍了如何在没有数据库的情况下验证令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在同一台服务器上托管了两个域,即域A和域B.

I have hosted two domains on the same server, domain A and domain B.

域A将生成对​​域B内容的唯一访问令牌.

Domain A will generate the unique access token to the content of domain B.

域A

<?php
  //http://php.net/manual/en/function.phpversion.php
  //echo 'Version of PHP: ' . phpversion();

  session_start();
  //$expiry_timestamp = time() + $expiry;
  //https://davidwalsh.name/random_bytes //https://secure.php.net/random_bytes
  //$token = bin2hex(random_bytes(64)); 
  $token = bin2hex(openssl_random_pseudo_bytes(64));
  //$time_token = 12000;
  //$time_token = srand(floor(time() / $time_token));
  //echo $token;
  $_SESSION['token']=$token;
?>

<html>
    <head>
    </head>

    <body>  
        <a href= "domainB.com/content1.php?token=<?php echo $_SESSION['token']; ?>">Content 1</a>
    </body>
</html>

生成令牌的过程似乎是正确的,生成令牌很容易.

The process of generating a token seems to be the right one, it has been easy to generate it.

现在出现了我的问题,如何验证从域A到域B生成的令牌?生成的令牌必须仅对生成令牌的内容有效,令牌对于其他内容必须无效,令牌必须唯一,这样,如果不是来自他或她计算机的用户就无法与其他用户共享访问权限,令牌必须仅在访问4个小时后才有效4个小时,令牌将不再有效以显示内容,必须生成新令牌才能再次访问.

Now comes my problem, how can I validate the generated token from domain A to domain B ?. The generated token must only be valid for the content that generated the token, the token must not be valid for other content, the token must be unique so that user can not share access to another user if it is not from his or her computer, the token must be valid only for 4 hrs of access after 4 hrs the token will no longer be valid to display the content must generate a new token to access again.

可以使用cookie而不使用数据库来完成此过程吗?

Can this process be done using a cookie without using a database?

也许使用密钥来标识域A和域B

Maybe identifying both domains A and B using a key, something like that

$APP_SECRET_KEY = "key code secret";

推荐答案

在这里使用共享密钥是一个好方法.

Using a shared secret key is a good approach here.

当我需要生成和验证令牌(例如:E)时,我倾向于使用 HMAC -邮件验证),并且不想将其存储在数据库中.另外, HMAC内置于PHP ,因此这里不需要库.

I tend to use HMAC when I need to generate and validate a token (e.g.: E-Mail verification) and don't want to store it in a DB. Plus, HMAC is built in to PHP, so no library is needed here.

这个想法是,在您的数据之上,添加一个签名以验证此令牌是由您的应用程序在域A上创建的.您再次以相同的方式在域B上生成该令牌以进行验证.

The idea is, on top of your data, you add a signature to verify that this token was created by your application on Domain A. You generate the token the same way again on Domain B to verify it.

示例:

用于生成令牌的共享函数:

Shared function to generate the token:

function buildVerificationToken($expires, $content)
{
    // Same function on both domains
    $APP_SECRET_KEY = 'key code secret';  // Maybe move that out of source code

    $tokenData = [
        'expires' => $expires, // Include it in signatur generation to prevent user from changing it in URL
        'content' => $content, // Create different token for different content
        'ip' => $_SERVER['REMOTE_ADDR'], // Identify the browser to make it not shareable. Best approach I could think of for this part.
    ];

    $serialized = json_encode($tokenData);

    return hash_hmac('sha256', $serialized, $APP_SECRET_KEY);
}

在域A上生成令牌:

<?php
$expires = time() + (4 * 3600); // +4h
?>
<a href= "domainB.com/content1.php?expires=<?php echo $expires; ?>&token=<?php echo buildVerificationToken($expires, 'content1'); ?>">Content 1</a>

在域B上进行验证:

$providedExpires = (int) $_GET['expires'];
$providedToken = $_GET['token'];

$verificationToken = buildVerificationToken($providedExpires, 'content1'); // Build token the same way

if (!hash_equals($verificationToken, $providedToken)) { // hash_equals instead of string comparison to prevent timing attacks
    // User provided forged token, token for another content, or another IP
    die('Bad token'); // However you want to handle this
}

if (time() > $providedExpires) { // Check expiry time. We can trust the user did not modify it as we checked the HMAC hash
    die('Token expired'); // However you want to handle this
}

// User is allowed to see content1

这篇关于如何在没有数据库的情况下验证令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆