我正在 Angular-12 项目中创建密码重置。我使用 Laravel-8 作为后端,使用 Angular-12 作为前端。
Laravel 后端(api):
public function create(Request $request)
{
$request->validate([
'email' => 'required|string|email',
]);
$user = User::where('email', $request->email)->first();
$passwordReset = PasswordReset::updateOrCreate(
['email' => $user->email],
[
'email' => $user->email,
'token' => str_random(60)
]
);
if ($user && $passwordReset)
$user->notify(
new PasswordResetRequest($passwordReset->token)
);
return response()->json([
'message' => 'We have e-mailed your password reset link!'
]);
}
当用户请求重置密码时,令牌会发送到他的电子邮件地址。
public function find($token)
{
$passwordReset = PasswordReset::where('token', $token)
->first();
if (!$passwordReset)
return response()->json([
'message' => 'This password reset token is invalid.'
], 404);
}
return response()->json($passwordReset);
}
public function reset(Request $request)
{
$request->validate([
'email' => 'required|string|email',
'password' => 'required|string|confirmed',
'token' => 'required|string'
]);
$passwordReset = PasswordReset::where([
['token', $request->token],
['email', $request->email]
])->first();
$user = User::where('email', $passwordReset->email)->first();
if (!$user)
return response()->json([
'message' => 'We can\'t find a user with that e-mail address.'
], 404);
$user->password = bcrypt($request->password);
$user->save();
$passwordReset->delete();
$user->notify(new PasswordResetSuccess($passwordReset));
return response()->json($user);
}
路线:
Route::group([
'namespace' => 'Auth',
'middleware' => 'api',
'prefix' => 'password'
], function () {
Route::post('create', 'PasswordResetController@create');
Route::get('find/{token}', 'PasswordResetController@find');
Route::post('reset', 'PasswordResetController@reset');
});
通知:
public function toMail($notifiable)
{
$url = url('https://myapp/reset-password/'.$notifiable->token);
return (new MailMessage)
->line('You are receiving this email because we received a password reset request for your account.')
->action('Reset Password', url($url))
->line('If you did not request a password reset, no further action is required.');
}
我还有在用户登录之前实现密码重置的 Angular 前端:
角度:
组件:
export class ResponseResetComponent implements OnInit {
isLoading = false;
isSubmitted = false;
resetForm!: FormGroup;
token!: string;
constructor(
private fb: FormBuilder,
private api: ApiService,
private router: Router,
private route: ActivatedRoute,
private store: Store < AppState > ,
) {
}
ngOnInit() {
this.createForm();
this.token = this.route.snapshot.paramMap.get('token') || '{}';
}
createForm() {
const formOptions: AbstractControlOptions = {
validators: MustMatch('password', 'confirmPassword')
};
this.resetForm = this.fb.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6), Validators.maxLength(50)]],
confirmPassword: ['', [Validators.required]]
}, formOptions);
}
get f() {
return this.resetForm.controls;
}
onSubmit() {
this.isSubmitted = true;
if (this.resetForm.invalid) {
return;
}
const formData = this.resetForm.getRawValue();
const data = {
email: formData.email,
password: formData.password,
confirmPassword: formData.confirmPassword,
};
const header = {
'Content-Type': 'application/json'
};
this.isLoading = true;
return this.api.get('password/find/' + this.token, header)
.pipe(first())
.subscribe(
data => this.resetHandler(data),
error => {
this.store.dispatch(loadErrorMessagesSuccess(error));
this.isLoading = false;
});
}
resetHandler(data: any) {
const header = {
'Content-Type': 'application/json'
};
return this.api.post('password/reset', data, header).subscribe(
() => {
this.router.navigateByUrl('/auth');
},
error => {
this.store.dispatch(loadErrorMessagesSuccess(error));
this.isLoading = false;
});
}
}
HTML:
<form [formGroup]="resetForm" (ngSubmit)="onSubmit()">
<div class="form-label-group">
<input type="email" formControlName="email" placeholder="Email" class="form-control" [ngClass]="{ 'is-invalid': isSubmitted && f.email.errors }" autofocus/>
<div *ngIf="isSubmitted && f.email.errors" class="invalid-feedback">
<div *ngIf="f.email.errors.required">Email is required</div>
<div *ngIf="f.email.errors.email">Email must be a valid email address</div>
</div>
</div>
<div class="form-label-group">
<input type="password" formControlName="password" placeholder="Password" class="form-control" [ngClass]="{ 'is-invalid': isSubmitted && f.password.errors }" />
<div *ngIf="isSubmitted && f.password.errors" class="invalid-feedback">
<div *ngIf="f.password.errors.required">Password is required</div>
<div *ngIf="f.password.errors.minlength">Password must be at least 6 characters</div>
<div *ngIf="f.password.errors.maxlength">Password cannot be more than 50 characters</div>
</div>
</div>
<div class="form-label-group">
<input type="password" formControlName="confirmPassword" placeholder="Confirm Password" class="form-control" [ngClass]="{ 'is-invalid': isSubmitted && f.confirmPassword.errors }" />
<div *ngIf="isSubmitted && f.confirmPassword.errors" class="invalid-feedback">
<div *ngIf="f.confirmPassword.errors.required">Confirm Password is required</div>
<div *ngIf="f.confirmPassword.errors.mustMatch">Passwords must match</div>
</div>
</div>
<button class="btn btn-lg btn-primary btn-block text-uppercase" type="submit" [disabled]="isLoading">
<span *ngIf="isLoading" class="spinner-border spinner-border-sm mr-1"></span>
Change Password
</button>
</form>
角度路由:
{ 路径:'重置密码/:令牌', 组件:RequestResetComponent, },
目前,它的工作方式是这样的:
由于密码重置是在用户登录之前完成的,我希望Angular表单能够自动加载用户邮箱,这样他在提交新密码时就不需要输入邮箱了。
我如何实现这一目标?
谢谢