在 Vapor 4 中注册新用户时如何保护我的路线?
How can I protect my routes when signing up a new user in Vapor 4?
我想知道我是否使用了此处的最佳做法,因为我以 Content-Type: application/json
方式发送用户凭据,没有保护密码。我想知道我是否可以使用中间件保护我的路由,并让用户以最安全的方式在我的 Vapor 4 应用程序上注册。
我可以使用 Authorization: Basic
在我的 Vapor 应用程序上注册用户吗?
我这里是正常流程吗?
这是我注册用户的方式。我的 table 与 UserModel,这是处理注册流程的扩展。
extension UserModel {
// MARK: UserSignUp
/// Values needed for a user to sign up.
///
struct SignUp {
let email: String
let password: String
}
}
extension UserModel.SignUp: Codable {}
extension UserModel.SignUp: Validatable {
/// Setting up sign up rules for email and password to validate
/// new user.
///
static func validations(_ validations: inout Validations) {
validations.add("email", as: String.self, is: .email)
validations.add("password", as: String.self, is: .count(1...))
}
}
我想保护它以安全传递用户凭据的路由。
struct UsersAuthController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let unprotectedRoute = routes.grouped("users")
unprotectedRoute.post("signup", use: signUp)
}
}
这是我在 Vapor 应用程序中注册用户的方式。这是最安全的方式吗?
extension UsersAuthController {
func signUp(_ req: Request) throws -> EventLoopFuture<UserModel.NewSession> {
try UserModel.SignUp.validate(content: req)
let signUpUser = try req.content.decode(UserModel.SignUp.self)
let user = try create(from: signUpUser)
var token: UserTokenModel!
return checkIfUserExists(signUpUser.email, req: req)
.flatMapThrowing { exists -> UserModel in
guard !exists else {
throw Abort(.conflict)
}
return user }
.flatMap { [=12=].save(on: req.db) }
.flatMapThrowing { _ -> UserTokenModel in
guard let newToken = try? user.createUserToken(source: .signUp) else {
throw Abort(.internalServerError)
}
token = newToken
return token }
.flatMap { [=12=].save(on: req.db) }
.flatMapThrowing {
UserModel.NewSession(token: token.value,
user: try user.asPublic()) // Just returning a token and use id.
}
}
func create(from user: UserModel.SignUp) throws -> UserModel {
UserModel(email: user.email,
password: try Bcrypt.hash(user.password))
}
}
你想防止什么?在 JSON body 中发送用户名和密码或作为 HTTP 基本凭据 header 发送用户名和密码并没有真正的区别。否则事情看起来没问题,尽管我会嵌套一些期货以避免 var token: UserTokenModel!
我想知道我是否使用了此处的最佳做法,因为我以 Content-Type: application/json
方式发送用户凭据,没有保护密码。我想知道我是否可以使用中间件保护我的路由,并让用户以最安全的方式在我的 Vapor 4 应用程序上注册。
我可以使用 Authorization: Basic
在我的 Vapor 应用程序上注册用户吗?
我这里是正常流程吗?
这是我注册用户的方式。我的 table 与 UserModel,这是处理注册流程的扩展。
extension UserModel {
// MARK: UserSignUp
/// Values needed for a user to sign up.
///
struct SignUp {
let email: String
let password: String
}
}
extension UserModel.SignUp: Codable {}
extension UserModel.SignUp: Validatable {
/// Setting up sign up rules for email and password to validate
/// new user.
///
static func validations(_ validations: inout Validations) {
validations.add("email", as: String.self, is: .email)
validations.add("password", as: String.self, is: .count(1...))
}
}
我想保护它以安全传递用户凭据的路由。
struct UsersAuthController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let unprotectedRoute = routes.grouped("users")
unprotectedRoute.post("signup", use: signUp)
}
}
这是我在 Vapor 应用程序中注册用户的方式。这是最安全的方式吗?
extension UsersAuthController {
func signUp(_ req: Request) throws -> EventLoopFuture<UserModel.NewSession> {
try UserModel.SignUp.validate(content: req)
let signUpUser = try req.content.decode(UserModel.SignUp.self)
let user = try create(from: signUpUser)
var token: UserTokenModel!
return checkIfUserExists(signUpUser.email, req: req)
.flatMapThrowing { exists -> UserModel in
guard !exists else {
throw Abort(.conflict)
}
return user }
.flatMap { [=12=].save(on: req.db) }
.flatMapThrowing { _ -> UserTokenModel in
guard let newToken = try? user.createUserToken(source: .signUp) else {
throw Abort(.internalServerError)
}
token = newToken
return token }
.flatMap { [=12=].save(on: req.db) }
.flatMapThrowing {
UserModel.NewSession(token: token.value,
user: try user.asPublic()) // Just returning a token and use id.
}
}
func create(from user: UserModel.SignUp) throws -> UserModel {
UserModel(email: user.email,
password: try Bcrypt.hash(user.password))
}
}
你想防止什么?在 JSON body 中发送用户名和密码或作为 HTTP 基本凭据 header 发送用户名和密码并没有真正的区别。否则事情看起来没问题,尽管我会嵌套一些期货以避免 var token: UserTokenModel!