问题描述
我正在做一个流利的小型蒸气项目。现在,我应该能够创建一个用户,为该创建的用户创建一个令牌,并使用会话令牌返回该用户。之后,我应该能够登录并创建一个新令牌。
现在的问题是,每当我创建令牌时,即使将令牌设置为id
,该令牌的1
值也会设置为nil
。创建用户时不会发生这种情况,然后自动增量将按预期工作。
我的迁移Createtokens.swift
:
import Fluent
struct Createtokens: Migration {
func prepare(on database: Database) -> EventLoopFuture<Void> {
database.schema(Token.schema)
.field("id",.int,.identifier(auto: true))
.unique(on: "id")
.field("user_id",.references("users","id"))
.field("value",.string,.required)
.unique(on: "value")
.field("created_at",.datetime,.required)
.field("expires_at",.datetime)
.create()
}
func revert(on database: Database) -> EventLoopFuture<Void> {
database.schema(Token.schema).delete()
}
}
我的令牌(Token.swift
):
import Vapor
import Fluent
final class Token: Model {
static let schema = "tokens"
@ID(custom: "id",generatedBy: .database)
var id: Int?
@Parent(key: "id")
var user: User
@Field(key: "value")
var value: String
@Field(key: "expires_at")
var expiresAt: Date?
@Timestamp(key: "created_at",on: .create)
var createdAt: Date?
init() {}
init(id: Int? = nil,userId: User.IDValue,token: String,expiresAt: Date?
) {
self.id = id
self.$user.id = userId
self.value = token
self.expiresAt = expiresAt
}
}
extension Token: ModelTokenAuthenticatable {
static let valueKey = \Token.$value
static let userKey = \Token.$user
var isValid: Bool {
guard let expiryDate = expiresAt else {
return true
}
return expiryDate > Date()
}
}
在我的用户结构中,当我创建令牌时:
func createtoken() throws -> Token {
let calendar = Calendar(identifier: .gregorian)
let expiryDate = calendar.date(byAdding: .year,value: 1,to: Date())
let token = try Token(userId: requireID(),token: [UInt8].random(count: 16).base64,expiresAt: expiryDate)
return token
}
如果我在return token
上设置一个断点并打印出令牌,则会得到以下信息:
(lldb) po token
Token(input: [expires_at: Optional(2021-11-11 21:01:10 +0000),value: "wn8kvw/GYSfqL280RLCDbQ==",id: 1])
该ID值设置为1
,但是在代码中(对我来说)很清楚,我已将其设置为nil
。即使我在返回之前添加了token.id = nil
,它仍然设置为1
。
解决方法
正如您所提到的,n - r
和id
属性似乎都使用了键“ id”,这是这种字符串类型的API中常见的错误类型。 / p>
我试图缓解这种情况的一种方法是扩展user
并强迫自己始终使用这些静态属性而不是字符串,这样IDE的自动完成功能为我提供了机会考虑要使用的正确的字段键-手动键入时会丢失的内容。
FieldKey
希望这对将来有帮助!
,我发现我花了至少1.5h来解决这个问题,这是一个愚蠢的错误。
问题出在:
@Parent(key: "id")
var user: User
应该以{{1}}作为键,而不是user_id
。现在,它将id重写为我发送的任何userId。