Je construis une API dans Yii 1.x qui sera utilisée avec une application mobile. Une partie du processus implique une connexion (avec un nom d'utilisateur et un mot de passe) à l'aide de la requête JSON suivante ci-dessous: -
// Demande envoyée avec nom d'utilisateur et mot de passe
{
"request" : {
"model" : {
"username" : "bobbysmith",
"password" : "mystrongpassword"
}
}
}
// Si connecté avec succès, retourne la réponse suivante
{
"response": {
"code": 200,
"message": "OK",
"model": {
"timestamp": 1408109484,
"token": "633uq4t0qdtd1mdllnv2h1vs32"
}
}
}
Ce jeton est très important - une fois qu'un utilisateur est connecté à l'application, je souhaite qu'il ait accès à d'autres pages qui le nécessitent. Je souhaite que l'application mobile enregistre ce jeton et si le même 633uq4t0qdtd1mdllnv2h1vs32 Le jeton est trouvé dans toutes les demandes ultérieures, il l'acceptera comme une demande authentifiée (pour cet utilisateur 'bobbysmith').
Je ne sais pas trop comment y parvenir. J'ai fait des recherches et je peux dire que oAuth a été mentionné à quelques reprises, de même que l'authentification de base via HTTPS.
Donc en un mot cette ...
Quelqu'un peut-il éventuellement expliquer le meilleur moyen d'y parvenir? S'il vous plaît laissez-moi savoir si ce que j'ai dit n'est pas clair à 100% et je fournirai plus d'informations.
Bien que j'utilise PHP, une solution Yii 1.x est idéale car c'est ce que l'API actuelle est construite.
En un mot, l'application garantit que chaque demande adressée au serveur inclut un jeton dans la charge utile ou l'en-tête afin que ce jeton puisse être récupéré sur chaque message suivant, une fois déconnecté, ce jeton est simplement supprimé OR défini sur null /vide
Concentrez-vous sur une solution fournissant à la fois toutes les bonnes choses relatives aux autorisations (RESTful), qui seront probablement:
Astuce: Les données personnelles de l'utilisateur devraient toujours être cryptées!
Ci-dessus, vous pouvez voir les informations standard sur les interfaces de sécurité. Pour assurer une sécurité durable, vous pouvez essayer comme dans la partie suivante. Je ne suis pas sûr de votre AppSidePersitence. Peut-être sa sqlLite ou quelque chose comme ça. C'est pourquoi je n'indique pas de schéma de base de données basé sur du code, comme je l'avais fait pour Yii. Vous aurez besoin d'un stockage/persistance dans votre application Yii (backend) et également dans votre application (client) pour stocker les temps et les jetons.
Votre 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;
Votre modèle AppPersitence
Gérer correctement votre jeton et assurer la sécurité de la connexion
Une fois que la connexion de l'utilisateur a été validée "succès" par Yii, vous générez un nouveau jeton d'utilisateur avec l'horodatage actuel, qui sera stocké dans votre base de données YiiApp. Dans votre YiiApp, vous devez configurer un "délai d'expiration", qui sera ajouté à l'horodatage actuel, par exemple, si vous souhaitez utiliser "horodatage": l'horodatage actuel est: 1408109484
et votre délai d'expiration est défini sur 3600
(qui est 3600 sec = 1h). Donc ... votre date d'expiration qui sera envoyée via l'API est (1408109484+3600)
. Btw. Astuce: Vous n'avez pas besoin d'envoyer des attributs tels que "code": 200
. Les codes de réponse sont inclus dans vos données d'en-tête Requests/Response.
** 200 OK Response-Example, après la connexion de l'utilisateur, contient la date "expirée" calculée: **
{
"error": null,
"content": {
"expires": 1408109484,
"token": "633uq4t0qdtd1mdllnv2h1vs32"
}
}
Important: Toutes les demandes que vous souhaitez sécuriser doivent être envoyées avec votre "jeton" généré. Ce qui sera probablement stocké dans votre deviceStorage. Vous pouvez gérer vos "états de connexion" - vraiment RESTful si vous utilisez HTTP-Response-Codes right, par exemple, 200 OK (si tout va bien) ou 401 (non autorisé, l'utilisateur n'est pas connecté ou en session. est expiré). Vous devez valider votre demande d'utilisateur côté Yii. Lire le jeton à partir des demandes entrantes, le valider en raison des jetons donnés dans la base de données et comparer la BD "créée" avec l'heure actuelle de la demande (requêtes HTTP).
** Exemple de demande, schéma par défaut pour toute demande de sécurité: **
{
"token": "633uq4t0qdtd1mdllnv2h1vs32"
"content": {
"someDataYouNeed" : null
}
}
** 401 Exemple de réponse non autorisée, jeton expiré: **
{
"error": 1, // errorCode 1: token is expired
"content": {
"someDataYouNeed" : null
}
}
** 401 Réponse non autorisée-Exemple, l'utilisateur n'est pas connecté (aucun jeton n'existe dans YiiDB): **
{
"error": 2, // errorCode 2: user is not logged in
"content": {
"someDataYouNeed" : null
}
}
Maintenir une session utilisateur active? C'est assez facile. Il suffit de mettre à jour "créé" -date dans authToken
- Table à l'heure actuelle de la demande. Faites-le à chaque fois, une demande valide a été envoyée par l'utilisateur. De cette façon, la session n'expirera pas si l'utilisateur est toujours actif. Assurez-vous que votre jeton de base de données n’a pas expiré avant de mettre à jour le champ expires
- Date dans la base de données. Si aucune demande n'est envoyée pendant l'expiration de la session, le maintien en vie ne sera plus possible.
Désolé, mais ajouter des codes PHP serait trop.
Si vous construisez pour une application mobile native, il serait judicieux de vous fier à la sécurité de la mémoire native (par exemple, le trousseau iOS) et non à une solution basée sur les cookies. Sinon, comment vous avez décrit semble bien. Tant que votre charge utile est envoyée via SSL, peu importe que le jeton soit dans le PUT ou dans le POST. La gestion de vos jetons (c'est-à-dire les délais d'expiration) sont des décisions que vous devez prendre. Back-end Je ferais ce que vous décrivez en maintenant le jeton dans votre base de données, puis supprimez-le lorsqu'il est devenu obsolète et renvoyez un message à votre application client pour le remettre en mode déconnecté/demander des informations d'identification.
EDIT: Découvrez cet impressionnant tut du prolifique Phil Sturgeon. Il possède également une excellente bibliothèque CI pour la construction d'API RESTful dans CI, qui mérite peut-être d'être étudié.
http://philsturgeon.uk/blog/2013/07/building-a-decent-api
http://code.tutsplus.com/tutorials/working-with-restful-services-in-codeigniter--net-8814
À ce stade, vous êtes probablement passé à Yii2 et la solution la plus propre consiste à utiliser les classes incluses pour les API RESTful, ou de les implémenter dans n’importe quel framework.
Source: HttpBearerAuth.php
Les avantages sont expliqués en détail dans cet article , mais pour résumer, il est préférable d’utiliser votre solution avec en-tête de requête, car les paramètres GET peuvent être sauvegardés dans des journaux et le mot de passe de utilisez pas SSL (vous devriez!)