使用令牌实现 RESTful API 身份验证 (Yii/Yii2) [英] Implementing an RESTful API Authentication using tokens (Yii/Yii2)

查看:43
本文介绍了使用令牌实现 RESTful API 身份验证 (Yii/Yii2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Yii 1.x 中构建一个 API,它将与移动应用程序一起使用.该过程的一部分涉及使用以下 JSON 请求进行登录(使用用户名和密码):-

//使用用户名 & 发送的请求密码

<代码>{要求" : {模型" : {用户名":鲍比史密斯",密码":我的强密码"}}}

//如果登录成功返回如下响应

<代码>{回复": {代码":200,"message": "好的",模型": {时间戳":1408109484,令牌":633uq4t0qdtd1mdllnv2h1vs32"}}}

此令牌非常重要 - 一旦用户登录应用程序,我希望他们能够访问需要他们登录的其他页面.我希望移动应用程序存储此令牌 &如果在任何后续请求中找到相同的 633uq4t0qdtd1mdllnv2h1vs32 令牌,它将接受这是经过身份验证的请求(对于此用户bobbysmith").

我有点不确定如何最好地做到这一点,我做了一些研究,oAuth 以及通过 HTTPS 的基本身份验证被提到过几次.

简而言之……

  1. 在移动应用主页上,用户使用他们的用户名正确登录 &密码 &这会向 API 发送请求.
  2. 这将返回一个带有当前时间戳的成功响应(如上所示)&最重要的令牌.
  3. 同一用户转到另一个应用页面/视图,其中 a) 需要此令牌,并且 b) 如果匹配,则验证该用户的身份(例如,以便他们可以编辑该帐户等.)
  4. 一旦用户点击退出",这个令牌就会被删除(并且可以继续访问我的帐户等)——本质上是一个基于令牌的身份验证系统.

谁能解释实现这一目标的最佳方法?如果我所说的不是 100% 清楚,请告诉我,我会提供更多信息.

当我使用 PHP 时,Yii 1.x 解决方案是理想的,因为它是当前 API 使用的构建.

简而言之,应用程序确保对服务器的每个请求都在有效负载或标头中包含令牌,因此可以在每个后续帖子中检索此令牌,一旦注销,此令牌将被简单地删除或设置为空/空

解决方案

有关处理安全接口的信息

专注于一次提供所有好的(RESTful)身份验证内容的解决方案,这可能是:

  • SSL(最重要的是,否则HTTP-Auth"就没有意义了,每个人都可以读出您的请求标头/正文 真的是 RESTful例如,200 OK(如果一切正常)或 401(未授权、用户未登录或会话已过期).您需要在 Yii 端验证您的用户请求.从传入请求中读取令牌,根据数据库中给定的令牌对其进行验证,并将创建的"-DB 与当前传入的请求时间(HTTP 请求)进行比较.

    ** 请求示例,任何安全请求的默认架构:**

    <代码>{令牌":633uq4t0qdtd1mdllnv2h1vs32"内容": {"someDataYouNeed" : null}}

    ** 401 Unauthorized Response-Example, token expired :**

    <代码>{"error": 1,//errorCode 1: 令牌已过期内容": {"someDataYouNeed" : null}}

    ** 401 Unauthorized Response-Example,用户未登录(YiiDB中不存在令牌):**

    <代码>{"error": 2,//errorCode 2: 用户未登录内容": {"someDataYouNeed" : null}}

  • 保持用户会话有效?这很容易.只需将 authToken-Table 中的created"-Date 更新为当前请求时间.每次都这样做,用户发送了一个有效的请求.这样,如果用户仍处于活动状态,会话就不会过期.在更新 DB 中的 expires-Date 字段之前,请确保您的 DB-Token 未过期.如果在会话到期时没有发送请求,则保活将不再可能.

    抱歉,添加 PHP 代码太多了.

  • I am building an API in Yii 1.x which will be used with a mobile application. Part of the process involves a login (with a username and password) using the following JSON request below:-

    // Request sent with username & password

    {
    "request" : {
        "model" : {
            "username" : "bobbysmith",
            "password" : "mystrongpassword"
        }
      }
    }
    

    // If successfully logged in return the following response

    {
    "response": {
        "code": 200,
        "message": "OK",
        "model": {
            "timestamp": 1408109484,
            "token": "633uq4t0qdtd1mdllnv2h1vs32"
        }
     }
    }
    

    This token is quite important - once a user is logged in on the app I'd like them to have access to other pages that require them to be logged in. I want the mobile app to store this token & if the same 633uq4t0qdtd1mdllnv2h1vs32 token is found within any subsequent requests it will accept this as being an authenticated request (for this user 'bobbysmith').

    I am a little unsure of how to best go about doing this, I have done some research and can oAuth has been mentioned a few times, along with Basic Authentication via HTTPS.

    So in a nutshell this...

    1. On mobile app homepage, user logs in correctly with their username & password & this sends a request to the API.
    2. This returns a successful response (shown above) with the current timestamp & the all important token.
    3. The same user goes to another app page/view where this token is a) required and b) if it matches up this authenticates that user (e.g so they can edit that account etc..)
    4. Once user clicks 'Logout' this token is then removed (and can longer access My Account etc..) - essentially a token based authentication system.

    Can anyone possibly explain the best way to achieve this? Please let me know if what I have stated isn't 100% clear and i'll provide more information.

    While I am using PHP, a Yii 1.x solution is ideal as that is what the current API is built using.

    In a nutshell, the app ensures that every request to server includes token in the payload or header so this token can be retrieved on every subsequent post, once logged out this token is simply removed OR set to null/empty

    解决方案

    Information about handling security interfaces

    Focus a solution which provides all the good (RESTful) auth stuff at once, which probably will be:

    • SSL (most IMPORTANT, else "HTTP-Auth" would be sence less, everyone would be able to read out your Request Header / Body Man-in-the-middle-attack)
    • oAuth (or better oAuth2!)
    • HTTP-Auth
    • Tokens (including a limited lifetime, refresh and maybe include IP/DeviceUID check logic-> if it's mobile!)
    • Salt generated passwords
    • Custom HTTP-Headers for ID/ENV/CLIENT checks or what ever.
    • Encrypted body data for Request and Response to prevent data manipulations

    Hint: Personal user data should be allways encrypted!


    Maybe a solution

    Above you can see the standard information about security interfaces. To ensure lasting security you can try it like in the next part. I'am not sure about your AppSidePersitence. Maybe its sqlLite or something like that. That's why I don't indicate a code-based DB-Schema, like I did it to Yii. You will need a storage/persistence inside your Yii application (backend) and also inside your app (client) to store times and tokens.

    Your YiiDBModel

    -- -----------------------------------------------------
    -- Table `mydb`.`user`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `mydb`.`user` (
      `id` INT NOT NULL,
      `username` VARCHAR(255) NOT NULL,
      `password` VARCHAR(255) NOT NULL,
      `lastLogin` DATETIME NULL,
      `modified` DATETIME NULL,
      `created` DATETIME NULL,
      PRIMARY KEY (`id`))
    ENGINE = InnoDB;
    
    ----------------------------------------------------
    -- Table `mydb`.`authToken`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `mydb`.`authToken` (
      `id` INT NOT NULL,
      `userId` INT NOT NULL,
      `token` VARCHAR(255) NOT NULL,
      `created` DATETIME NOT NULL,
      PRIMARY KEY (`id`, `userId`),
      INDEX `fk_authToken_user_idx` (`userId` ASC),
      UNIQUE INDEX `token_UNIQUE` (`token` ASC),
      CONSTRAINT `fk_authToken_user`
        FOREIGN KEY (`userId`)
        REFERENCES `mydb`.`user` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    

    Your AppPersitenceModel

    Handling your token right and ensure login security

    1. Any token you generate on Yii-Application side will be stored with a "created"-Datetime in your YiiApp-Database (see table authToken). Each user has only one "token", which will generated after a correct "login"-Request. In that way, you don't need to check tokens while "login". Defined by the schema, "token" is unique! I think there is no need to handle historical data (old tokens which are expired).
    2. Once the user-login was validated as "success" by Yii you generate a new user-token with current timestamp, which will be stored in your YiiApp-DB. In your YiiApp you need to configured a "expire time", which will be added to the current timestamp, for example, if you like to use "timestamps": Current timestamp is: 1408109484 and your expire time is set to 3600 (which is 3600 sec = 1h). So ... your expire datetime which will be send via API is (1408109484+3600). Btw. Hint: You don't need to send attributes like "code": 200. Response-Codes are included in your Requests/Response-Header-Data.

      ** 200 OK Response-Example, after user-login was successful, holds the calculated "expired"-date:**

       {
          "error": null,
          "content": {
              "expires": 1408109484,
              "token": "633uq4t0qdtd1mdllnv2h1vs32"
          }
      }
      

    3. Important: Every requests which you want to be secured, needs to be send with your generated User-"token". Which will probably stored in your deviceStorage. You can handle your "login-states"- really RESTful if you using HTTP-Response-Codes right, for example, 200 OK (if all is fine) or 401 (not authorized, user is not loged in or session is expired). You need to validate your User-Request's on Yii side. Read out the token from incoming requests, validate it due to given tokens in database and compare "created"-DB with the current incoming Request-Time (HTTP-Requests).

      ** Request-Example, default schema on any security requests:**

      {
          "token": "633uq4t0qdtd1mdllnv2h1vs32"
          "content": {
              "someDataYouNeed" : null
          }
      }
      

      ** 401 Unauthorized Response-Example, token expired :**

      {
          "error": 1, // errorCode 1: token is expired
          "content": {
              "someDataYouNeed" : null
          }
      }
      

      ** 401 Unauthorized Response-Example, user is not logged in (no token exists in YiiDB):**

      {
          "error": 2, // errorCode 2: user is not logged in
          "content": {
              "someDataYouNeed" : null
          }
      }
      

    4. Keep a User-Session alive? That's pretty easy. Just update "created"-Date in authToken-Table to the current request time. Do that every time, a valid request was send by the user. In that way, the session will not expire, if the user is still active. Ensure, your DB-Token is not expired, before updating expires-Date field in DB. If no request be send while the session expires, the keep alive won't be possible anymore.

      Sorry, but adding PHP-Codes would be too much.

    这篇关于使用令牌实现 RESTful API 身份验证 (Yii/Yii2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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