node.js - 如何在 Angular 8 中验证登录和注册表单
问题描述
我试图在我的应用程序中实现登录和注册表单,一切正常,但后端验证除外。后端验证不起作用,如错误消息“用户已存在”和“用户不存在”。我不知道如何实现它。如果有人知道请帮忙。
我从这里获得了用于登录和注册的脚本: https ://github.com/ArjunAranetaCodes/MoreCodes-Youtube/tree/master/mean-mongodb-login-reg
路线/Users.js:
const express = require('express')
const users = express.Router()
const cors = require('cors')
const jwt = require('jsonwebtoken')
const User = require('../models/User')
users.use(cors())
process.env.SECRET_KEY = 'secret'
users.post('/register', (req, res) => {
const today = new Date()
const userData = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: req.body.password,
created: today
}
User.findOne({
email: req.body.email
})
//TODO bcrypt
.then(user => {
if (!user) {
User.create(userData)
.then(user => {
const payload = {
_id: user._id,
first_name: user.first_name,
last_name: user.last_name,
email: user.email
}
let token = jwt.sign(payload, process.env.SECRET_KEY, {
expiresIn: 1440
})
res.json({ token: token })
})
.catch(err => {
res.send('error: ' + err)
})
} else {
res.json({ error: 'User already exists' })
}
})
.catch(err => {
res.send('error: ' + err)
})
})
users.post('/login', (req, res) => {
User.findOne({
email: req.body.email
})
.then(user => {
if (user) {
const payload = {
_id: user._id,
first_name: user.first_name,
last_name: user.last_name,
email: user.email
}
let token = jwt.sign(payload, process.env.SECRET_KEY, {
expiresIn: 1440
})
res.json({ token: token })
} else {
res.json({ error: 'User does not exist' })
}
})
.catch(err => {
res.send('error: ' + err)
})
})
users.get('/profile', (req, res) => {
var decoded = jwt.verify(req.headers['authorization'], process.env.SECRET_KEY)
User.findOne({
_id: decoded._id
})
.then(user => {
if (user) {
res.json(user)
} else {
res.send('User does not exist')
}
})
.catch(err => {
res.send('error: ' + err)
})
})
module.exports = users
register.component.html:
<div class="container">
<div class="row">
<div class="col-md-6 mt-5 mx-auto">
<form (submit)="register()">
<h1 class="h3 mb-3 font-weight-normal">Register</h1>
<div class="form-group">
<label for="name">First name</label>
<input type="text" class="form-control" name="first_name" placeholder="Enter your first name" [(ngModel)]="credentials.first_name">
</div>
<div class="form-group">
<label for="name">Last name</label>
<input type="text" class="form-control" name="last_name" placeholder="Enter your lastname name" [(ngModel)]="credentials.last_name">
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" name="email" placeholder="Enter email" [(ngModel)]="credentials.email">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" placeholder="Password" [(ngModel)]="credentials.password">
</div>
<button type="submit" class="btn btn-lg btn-primary btn-block">Register!</button>
</form>
</div>
</div>
</div>
register.component.ts:
import { Component } from '@angular/core'
import { AuthenticationService, TokenPayload } from '../authentication.service'
import { Router } from '@angular/router'
@Component({
templateUrl: './register.component.html'
})
export class RegisterComponent {
credentials: TokenPayload = {
_id: '',
first_name: '',
last_name: '',
email: '',
password: ''
}
constructor(private auth: AuthenticationService, private router: Router) {}
register() {
this.auth.register(this.credentials).subscribe(
() => {
this.router.navigateByUrl('/profile')
},
err => {
console.error(err)
}
)
}
}
login.component.html:
<div class="container">
<div class="row">
<div class="col-md-6 mt-5 mx-auto">
<form (submit)="login()">
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" name="email" placeholder="Enter email" [(ngModel)]="credentials.email">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" placeholder="Password" [(ngModel)]="credentials.password">
</div>
<button type="submit" class="btn btn-lg btn-primary btn-block">Sign in</button>
</form>
</div>
</div>
</div>
login.component.ts:
import { Component } from '@angular/core'
import { AuthenticationService, TokenPayload } from '../authentication.service'
import { Router } from '@angular/router'
@Component({
templateUrl: './login.component.html'
})
export class LoginComponent {
credentials: TokenPayload = {
_id: '',
first_name: '',
last_name: '',
email: '',
password: ''
}
constructor(private auth: AuthenticationService, private router: Router) {}
login() {
this.auth.login(this.credentials).subscribe(
() => {
this.router.navigateByUrl('/profile')
},
err => {
console.error(err)
}
)
}
}
身份验证.service.ts:
import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { Observable, of } from 'rxjs'
import { map } from 'rxjs/operators'
import { Router } from '@angular/router'
export interface UserDetails {
_id: string
first_name: string
last_name: string
email: string
password: string
exp: number
iat: number
}
interface TokenResponse {
token: string
}
export interface TokenPayload {
_id: string
first_name: string
last_name: string
email: string
password: string
}
@Injectable()
export class AuthenticationService {
private token: string
constructor(private http: HttpClient, private router: Router) {}
private saveToken(token: string): void {
localStorage.setItem('usertoken', token)
this.token = token
}
private getToken(): string {
if (!this.token) {
this.token = localStorage.getItem('usertoken')
}
return this.token
}
public getUserDetails(): UserDetails {
const token = this.getToken()
let payload
if (token) {
payload = token.split('.')[1]
payload = window.atob(payload)
return JSON.parse(payload)
} else {
return null
}
}
public isLoggedIn(): boolean {
const user = this.getUserDetails()
if (user) {
return user.exp > Date.now() / 1000
} else {
return false
}
}
public register(user: TokenPayload): Observable<any> {
const base = this.http.post(`/users/register`, user)
const request = base.pipe(
map((data: TokenResponse) => {
if (data.token) {
this.saveToken(data.token)
}
return data
})
)
return request
}
public login(user: TokenPayload): Observable<any> {
const base = this.http.post(`/users/login`, user)
const request = base.pipe(
map((data: TokenResponse) => {
if (data.token) {
this.saveToken(data.token)
}
return data
})
)
return request
}
public profile(): Observable<any> {
return this.http.get(`/users/profile`, {
headers: { Authorization: ` ${this.getToken()}` }
})
}
public logout(): void {
this.token = ''
window.localStorage.removeItem('usertoken')
this.router.navigateByUrl('/')
}
}
解决方案
在 routes/Users.js 中包含这段代码
users.post('/register', async(req, res) => {
try {
const exists = await User.findOne({ email: req.body.email})
if(exists == null){
res.statusCode = 200;
res.setHeader('Content-type', 'application/json');
res.json({success: true, status: 'You are allowed to register'});
}else{
res.statusCode=200;
res.setHeader('Content-type', 'application/json');
res.json({status: 'User already exists'});
}
}catch(error) {
res.status(500).send({message: "Error checking"});
}
})
就像我所做的那样,如果用户的电子邮件存在于数据库的用户模式中,那么它将不允许您注册。您也可以根据需要使用任何其他字段,例如名字或姓氏。希望这可以帮助。
您需要进行更改,例如让用户注册而不是此代码中的“您被允许注册”。
推荐阅读
- sql - 多个 UNION 可能更好的 SQL 查询 - 获取不同“键”名称的最新 5 条记录
- spring-cloud-stream - Spring Cloud Stream 和 Spring RetryTemplate 处理嵌套异常
- javascript - 无法使用 discord.js 获得角色
- git - 如何删除 .git 的大包文件?
- java - 如何查找重复的数组列表对象并将少数字段与唯一键合并
- java - MapStruct 映射不相关的相似类
- java - 查找字符串中打开的闭合 html 标记的数量
- c++ - 尝试在 C++ 中实现固定大小的队列时出现分段错误
- drag-and-drop - PyQt5 使用来自另一个文件的 Drop_groupBox()
- r - 找出组中的所有列在 R 中是否一致