Vapor 4认证
Vapor 4 authentication
嘿,我在登录时遇到了一些问题 controllers.My 代码是:
func login(_ req: Request) throws -> EventLoopFuture<UserToken>{
let user = try req.auth.require(User.self)
let token = try user.generateToken()
return token.save(on: req.db).map { token }
}
但我真的不知道 postman.This 中的函数是如何工作的是我的用户模型 :
import Foundation
import Fluent
import Vapor
import FluentPostgresDriver
final class User:Model,Content{
static let schema = "user"
@ID(key: .id)
var id:UUID?
@Field(key:"帳號")
var account:String
@Field(key: "密碼")
var password:String
init() {}
init(id: UUID?=nil, account:String, password:String){
self.id=id
self.account=account
self.password=password
}
}
extension User: ModelAuthenticatable {
// 要取帳號的欄位
static var usernameKey: KeyPath<User, Field<String>> = \User.$account
// 要取雜湊密碼的欄位
static var passwordHashKey: KeyPath<User, Field<String>> = \User.$password
// 驗證
func verify(password: String) throws -> Bool {
try Bcrypt.verify(password, created: self.password)
}
}
extension User {
struct Create: Content {
var account: String
var password: String
var confirmPassword: String // 確認密碼
}
}
extension User.Create: Validatable {
static func validations(_ validations: inout Validations) {
validations.add("account", as: String.self, is: .count(10...10))
// password需為8~16碼
validations.add("password", as: String.self, is: .count(8...16))
}
}
extension User {
func generateToken() throws -> UserToken {
// 產生一組新Token, 有效期限為一天
let calendar = Calendar(identifier: .gregorian)
let expiryDate = calendar.date(byAdding: .day, value: 1, to: Date())
return try UserToken(value: [UInt8].random(count: 16).base64, expireTime: expiryDate, userID: self.requireID())
}
}
这是我的用户令牌:
import Foundation
import Vapor
import Fluent
final class UserToken: Content, Model {
static let schema: String = "user_tokens"
@ID(key: .id)
var id: UUID?
@Field(key: "value")
var value: String
// oken過期時間
@Field(key: "expireTime")
var expireTime: Date?
// 關聯到User
@Parent(key: "user_id")
var user: User
init() { }
init(id: UUID? = nil, value: String, expireTime: Date?, userID: User.IDValue) {
self.id = id
self.value = value
self.expireTime = expireTime
self.$user.id = userID
}
}
extension UserToken: ModelTokenAuthenticatable {
//Token的欄位
static var valueKey = \UserToken.$value
//要取對應的User欄位
static var userKey = \UserToken.$user
// 驗證,這裡只檢查是否過期
var isValid: Bool {
guard let expireTime = expireTime else { return false }
return expireTime > Date()
}
}
当我输入“帐户”、“密码”和“确认密码”的值时,它一直告诉我“用户未通过身份验证”。 ,我的数据库中已经有了这个值。
enter image description here
而且我确定密码是正确的。有什么我错过的吗?我对蒸汽很陌生。
我关注了下面的文章:https://ken-60401.medium.com/vapor-4-authentication-server-side-swift-1f96b035a117
我认为链接的教程对登录路由使用 HTTP 基本身份验证,我猜根据显示的代码判断情况就是如此(最好显示您如何注册登录路由)。
如果是这种情况,那么您需要在请求中发送用户名和密码作为 Authorization
header 中的基本身份验证凭据。该值应为 Basic <Credentials>
,其中 Credentials
是 username:password
Base 64 编码。然而you can get Postman to do it for you
嘿,我在登录时遇到了一些问题 controllers.My 代码是:
func login(_ req: Request) throws -> EventLoopFuture<UserToken>{
let user = try req.auth.require(User.self)
let token = try user.generateToken()
return token.save(on: req.db).map { token }
}
但我真的不知道 postman.This 中的函数是如何工作的是我的用户模型 :
import Foundation
import Fluent
import Vapor
import FluentPostgresDriver
final class User:Model,Content{
static let schema = "user"
@ID(key: .id)
var id:UUID?
@Field(key:"帳號")
var account:String
@Field(key: "密碼")
var password:String
init() {}
init(id: UUID?=nil, account:String, password:String){
self.id=id
self.account=account
self.password=password
}
}
extension User: ModelAuthenticatable {
// 要取帳號的欄位
static var usernameKey: KeyPath<User, Field<String>> = \User.$account
// 要取雜湊密碼的欄位
static var passwordHashKey: KeyPath<User, Field<String>> = \User.$password
// 驗證
func verify(password: String) throws -> Bool {
try Bcrypt.verify(password, created: self.password)
}
}
extension User {
struct Create: Content {
var account: String
var password: String
var confirmPassword: String // 確認密碼
}
}
extension User.Create: Validatable {
static func validations(_ validations: inout Validations) {
validations.add("account", as: String.self, is: .count(10...10))
// password需為8~16碼
validations.add("password", as: String.self, is: .count(8...16))
}
}
extension User {
func generateToken() throws -> UserToken {
// 產生一組新Token, 有效期限為一天
let calendar = Calendar(identifier: .gregorian)
let expiryDate = calendar.date(byAdding: .day, value: 1, to: Date())
return try UserToken(value: [UInt8].random(count: 16).base64, expireTime: expiryDate, userID: self.requireID())
}
}
这是我的用户令牌:
import Foundation
import Vapor
import Fluent
final class UserToken: Content, Model {
static let schema: String = "user_tokens"
@ID(key: .id)
var id: UUID?
@Field(key: "value")
var value: String
// oken過期時間
@Field(key: "expireTime")
var expireTime: Date?
// 關聯到User
@Parent(key: "user_id")
var user: User
init() { }
init(id: UUID? = nil, value: String, expireTime: Date?, userID: User.IDValue) {
self.id = id
self.value = value
self.expireTime = expireTime
self.$user.id = userID
}
}
extension UserToken: ModelTokenAuthenticatable {
//Token的欄位
static var valueKey = \UserToken.$value
//要取對應的User欄位
static var userKey = \UserToken.$user
// 驗證,這裡只檢查是否過期
var isValid: Bool {
guard let expireTime = expireTime else { return false }
return expireTime > Date()
}
}
当我输入“帐户”、“密码”和“确认密码”的值时,它一直告诉我“用户未通过身份验证”。 ,我的数据库中已经有了这个值。 enter image description here
而且我确定密码是正确的。有什么我错过的吗?我对蒸汽很陌生。 我关注了下面的文章:https://ken-60401.medium.com/vapor-4-authentication-server-side-swift-1f96b035a117
我认为链接的教程对登录路由使用 HTTP 基本身份验证,我猜根据显示的代码判断情况就是如此(最好显示您如何注册登录路由)。
如果是这种情况,那么您需要在请求中发送用户名和密码作为 Authorization
header 中的基本身份验证凭据。该值应为 Basic <Credentials>
,其中 Credentials
是 username:password
Base 64 编码。然而you can get Postman to do it for you