Angular - 如何在密码重置的文本字段上自动输入电子邮件

时间:2021-07-27 08:46:19

标签: angular laravel

我正在 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, },

目前,它的工作方式是这样的:

  1. 当用户请求(在他登录之前)重置密码时,令牌会发送到他的电子邮件并通过令牌路由以重置他的密码。他输入电子邮件和新密码。

由于密码重置是在用户登录之前完成的,我希望Angular表单能够自动加载用户邮箱,这样他在提交新密码时就不需要输入邮箱了。

我如何实现这一目标?

谢谢

0 个答案:

没有答案
相关问题