问题描述
我想知道我是否使用了此处的最佳做法,因为我以 Content-Type: application/json
方式发送用户凭据,而不保护密码。我想知道我是否可以使用中间件保护我的路由,并让用户以最安全的方式在我的 Vapor 4 应用程序上注册。
我可以使用 Authorization: Basic
在我的 Vapor 应用上注册用户吗?
这是我在这里做的正常流程吗?
这是我注册用户的方式。有我的 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",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 { $0.save(on: req.db) }
.flatMapThrowing { _ -> UserTokenModel in
guard let newToken = try? user.createuserToken(source: .signUp) else {
throw Abort(.internalServerError)
}
token = newToken
return token }
.flatMap { $0.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 正文中发送用户名和密码或作为 HTTP Basic 凭据标头发送之间没有真正的区别。否则事情看起来不错,尽管我会嵌套一些期货以避免var token: UserTokenModel!