简单项目中,一般会用到验证码登录。
一.实现需求:
验证码配合用户密码进行登录验证。
甭管它是短信验证码,数字验证码,还是图形拼图验证码。今日简短小结数字验证码。
二,关键代码
1,html中
<div class="item">
<ion-label>验证码</ion-label>
<ion-input placeholder="请输入验证码" clearInput maxlength="4" [(ngModel)]="loginForm.authCode"></ion-input>
<img class="authCode" [src]="authCodeImg" (click)="getWebGenAuthCode()">
</div>
2.ts
loginForm = {
username: '',
password: '',
// authCode: ''
// returnUrl:''
grant_type: 'password',
scope: 'all',
client_id : 'admin',
client_secret: '123456',
auth_type: 'username',
};
authCodeImg: string = '' // 验证码图片
showPassword: boolean = false; // 显示密码
constructor(private rest: RestService,
private storageService: StorageService,
private loadingCtrl: LoadingController,
private toastCtrl: ToastController,
private navCtrl: NavController,
public appService: AppService) { super(); }
ngOnInit() {
}
//获取验证码
getWebGenAuthCode() {
this.showLoading(this.loadingCtrl, '加载中...').then((loading) => {
this.rest.apiGetPic(this.rest.webGenAuthCode)
.subscribe((res: any) => {
this.authCodeImg = this.getImg(String.fromCharCode.apply(null, new Uint8Array(res)));
loading.dismiss();
}, (err) => {
this.toastError(this.toastCtrl, '连接失败');
loading.dismiss();
});
});
}
// 删除返回BASE64多余的转义字符
getImg(val): string {
let value = 'data:image/png;base64,' + val;
if (value == null || value == "" || value == undefined) {
return "";
} else {
var str = value.replace(/\ +/g, "");
str = str.replace(/[\r\n]/g, "");
return str;
}
}
ionViewWillEnter() {
this.getStorage();
// this.getWebGenAuthCode();
}
// 获取缓存的用户名,密码
getStorage() {
this.loginForm.username = this.storageService.getStorage('username');
this.loginForm.password = this.storageService.getStorage('password');
}
async login() {
this.showLoading(this.loadingCtrl, '登陆中...').then((loading) => {
this.rest.apiPost(this.loginForm, this.rest.login)
.subscribe((res) => {
if (res.status === 200) {
console.log(res)
const token = res.data.token;
this.storageService.setToken(token);
this.storageService.setStorage('username', this.loginForm.username);
this.storageService.setStorage('password', this.loginForm.password);
this.goBack();
this.toastSuccess(this.toastCtrl, res.msg);
} else {
this.toastError(this.toastCtrl, res.msg);
}
loading.dismiss();
}, (err) => {
this.toastError(this.toastCtrl, err.msg);
loading.dismiss();
});
});
}
// 判断是否可以登录
judgeCondition() {
let enable = false;
if (this.loginForm.username != '' && this.loginForm.password != '' && this.loginForm.authCode.length === 4) {
enable = true;
}
if (this.loginForm.username != '' && this.loginForm.password != '' ) {
enable = true;
}
return enable;
}
完整的html
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button (click)="goBack()">
<ion-icon name="chevron-back-outline"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title>登录</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="login">
<img class="logo" src="../../../assets/imgs/logo.png" />
<div class="item">
<ion-label>用户名</ion-label>
<ion-input placeholder="请输入用户名" clearInput [(ngModel)]="loginForm.username"></ion-input>
</div>
<div class="item">
<ion-label>密码</ion-label>
<ion-input placeholder="请输入密码" clearInput *ngIf="!showPassword" type="password" [(ngModel)]="loginForm.password"></ion-input>
<ion-input placeholder="请输入密码" clearInput *ngIf="showPassword" [(ngModel)]="loginForm.password"></ion-input>
<ion-icon name="eye" color="medium" (click)="showPassword=!showPassword"></ion-icon>
</div>
<div class="item">
<ion-label>验证码</ion-label>
<ion-input placeholder="请输入验证码" clearInput maxlength="4" [(ngModel)]="loginForm.authCode"></ion-input>
<img class="authCode" [src]="authCodeImg" (click)="getWebGenAuthCode()">
</div>
<div class="primary-btn gray-btn" *ngIf="!judgeCondition()">登录</div>
<div (click)="login()" class="primary-btn" *ngIf="judgeCondition()">登录</div>
<div (click)="loginByTourist()" class="primary-btn">游客登录</div>
<div class="operation">
<div class="operation-item" [routerLink]="['/reg']">手机快速注册</div>
<div class="operation-item" [routerLink]="['/forget-password']">忘记密码</div>
</div>
</div>
</ion-content>
三,token配置
位置
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpResponse,
} from '@angular/common/http';
import * as qs from 'qs';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Router } from '@angular/router';
import { StorageService, RestService } from '../service';
import { environment } from '../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class SetTokenHeaderInterceptor implements HttpInterceptor {
constructor(
private token: StorageService,
private router: Router,
private rest: RestService, ) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
const token = localStorage.getItem("token")
const { body, method, headers, url } = req;
const customerHeaders = {
// Authorization: token,
'Content-Type': headers.get('Content-Type') || 'application/x-www-form-urlencoded',
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT',
// 'Accept': 'application/json',
};
const urlList = [
// this.rest.serviceList,
// this.rest.serviceTypeList,
// this.rest.discoveryList,
// this.rest.discoveryTypeList,
this.rest.homepageList,
];
if (urlList.indexOf(url) === -1) {
console.log(token)
customerHeaders['Authorization'] = token;
// customerHeaders['QZH_TOKEN'] = token;//修改
}
const reqWithToken = req.clone({
// url: environment.apiUrl + url,
setHeaders: customerHeaders,
body: method.toLocaleLowerCase() === 'post' || !headers.get('Content-Type') ? qs.stringify(body) : body
});
return next.handle(reqWithToken)
.pipe(
tap(
(event) => {
if (event instanceof HttpResponse) {
const { status } = event.body;
switch (status) {
case 400:
this.router.navigate(['/login']);
// this.navCtrl.navigateRoot('/login');
break;
}
}
}
)
);
}
}
四,实现效果