700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > [Angular实战网易云]——26 登录/登出

[Angular实战网易云]——26 登录/登出

时间:2019-01-31 14:40:14

相关推荐

[Angular实战网易云]——26 登录/登出

登录实现

就目前的进度来看,是没有实现token验证的,所以所有的登录也只是简单的验证账密,即使账密的复写也只是存在localstorage内存中的,所以关于更加安全的登录不知道后面会不会修改。

切换弹窗页面

开始实现的default页面只是用来判断登录还是注册,所以说这一步的操作还是要更换弹窗内的渲染内容的。

将创建好的登录模块和注册模块添加到ponent.html中的wy-layer-modal标签内。

ponent.html

<app-wy-layer-modal><app-wy-layer-login name="login" [wyRememberLogin]="wyRememberLogin" (onChangeModalType)="onChangeModalType($event)" (onLogin)="onLogin($event)"></app-wy-layer-login><app-wy-layer-default name="default" (onChangeModalType)="onChangeModalType($event)"></app-wy-layer-default><app-wy-layer-register name="register" (onChangeModalType)="onChangeModalType($event)"></app-wy-layer-register></app-wy-layer-modal>

这样在选择弹框子页面时根据name值来判断。

ponent.html

<ul><li nz-menu-item (click)="openModalByMenu('loginByPhone')"><i nz-icon nzType="mobile" nzTheme="outline"></i>手机登录</li><li nz-menu-item (click)="openModalByMenu('register')"><i nz-icon nzType="user-add" nzTheme="outline"></i>注册</li></ul>

ponent.ts

private memberBatchActionsServer: MemberBatchActionsService,openModalByMenu (type: 'loginByPhone' | 'register') {if (type === 'loginByPhone') {this.openModal(ModalTypes.LoginByPhone);} else {this.openModal(ModalTypes.Register);}}// 打开弹窗openModal (type: ModalTypes) {this.memberBatchActionsServer.controlModal(true, type);}

当点击登录或者注册时,就会通过参数的不通来判断当前需要设置哪一种状态,当wy-layer-modal中的Store监听到状态的改变就会根据当前改变后的状态改变渲染内容。因此在占位处使用ngSwitch指令。

wy-layer-ponent.html

<ng-container [ngSwitch]="currentModalType"><ng-container *ngSwitchCase="'loginByPhone'"><ng-content select="[name=login]"></ng-content></ng-container><ng-container *ngSwitchCase="'register'"><ng-content select="[name=register]"></ng-content></ng-container><ng-container *ngSwitchDefault><ng-content ></ng-content></ng-container></ng-container>

有关ngSwitch指令的使用可以点击浏览

实现接口

member.service.ts

登录后需要显示当前登录人的一些信息,所以也需要获取当前登录人的个别数据。

// 登录login (formValue: LoginParams): Observable<User> {const querystring = require("querystring");const params = new HttpParams({fromString: querystring.stringify(formValue) });console.log('stringify:', params);return this.http.get(this.uri + 'login/cellphone', {params }).pipe(map(res => res as User))}// 获取用户信息getUserInfo (uid: string): Observable<User> {const params = new HttpParams().set('uid', uid);return this.http.get(this.uri + 'user/detail', {params }).pipe(map(res => res as User))}// 退出logOut (): Observable<SampleBack> {return this.http.get(this.uri + 'logout').pipe(map(res => res as SampleBack));}

这里出了一点问题: 在格式化数据的时候,使用query-string类的时候一直报错,虽然使用了一些解决方案,但是都是不起效的。然后就用了最原始的require引用,这点还真是不明白为什么

响应式表单

wy-layer-ponent.html

<div class="login-phone modal-content"><div class="modal-wrap"><form nz-form class="login-form" [formGroup]="formModel" (ngSubmit)="onSubmit()"><nz-form-item><nz-form-control nzHasFeedback nzErrorTip="请输入正确的手机号"><nz-input-group nzPrefixIcon="mobile"><input type="tel" nz-input placeholder="请输入手机号" formControlName="phone"></nz-input-group></nz-form-control></nz-form-item><nz-form-item><nz-form-control nzHasFeedback nzErrorTip="请输入正确的密码"><nz-input-group nzPrefixIcon="lock"><input type="password" nz-input placeholder="请输入密码" formControlName="password"></nz-input-group></nz-form-control></nz-form-item><nz-form-item><nz-form-control><div class="tools"><label nz-checkbox class="remember" formControlName="remember"><span>记住密码</span></label></div><button nz-button class="login-form-button" [disabled]="!formModel.valid" nzType="primary" nzBlock>登陆</button></nz-form-control></nz-form-item></form></div></div><div class="m-footer clearfix"><a (click)="onChangeModalType.emit('default')"> < 其它登陆方式</a><a (click)="onChangeModalType.emit('register')">没有账号?免费注册</a></div>

wy-layer-ponent.ts

export type LoginParams = {phone: number,password: string,remember: boolean,}formModel: FormGroup;@Input() wyRememberLogin: LoginParams;@Output() onChangeModalType = new EventEmitter<string | void>();@Output() onLogin = new EventEmitter<LoginParams>();constructor(private fb: FormBuilder) {}ngOnInit (): void {this.formModel = this.fb.group({phone: ['', [Validators.required, Validators.pattern(/^1\d{10}$/)]],password: ['', [Validators.required, Validators.minLength(6)]],remember: [false]})}ngOnChanges (changes: SimpleChanges): void {const userLoginParams = changes.wyRememberLogin;if (userLoginParams) {let phone = '';let password = '';let remember = false;if (userLoginParams.currentValue) {const value = codeJson(userLoginParams.currentValue, 'decode');phone = value.phone;password = value.password;remember = value.remember;}this.setModal({phone, password, remember });}}private setModal ({phone, password, remember }) {this.formModel = this.fb.group({phone: [phone, [Validators.required, Validators.pattern(/^1\d{10}$/)]],password: [password, [Validators.required, Validators.minLength(6)]],remember: [remember]})}onSubmit () {const modal = this.formModel;if (modal.valid) {this.onLogin.emit(modal.value);}}

使用formbuilder模块能够快速的创建表单类,使用其来创建一个包含手机号,密码和复选框的一个组,然后再DOM中绑定其formname属性即可。

有一点不得不说,会用正则是真的可以方便很多——但是我不会

此页面只是展示,所有的逻辑都放到了父组件中,所以当点击登录时将表单的值发射给父组件即可。

当父组件接收到传来的值后,就会调用登录接口。

ponent.ts

user: User;wyRememberLogin: LoginParams;constructor(private searchServe: SearchService,private store$: Store<AppModule>,private memberBatchActionsServer: MemberBatchActionsService,private memberServe: MemberService,private message: NzMessageService,private storageServe: StorageService,) {const userId = this.storageServe.getStorage('wyUserId');if (userId) {this.store$.dispatch(SetUserId({id: userId }));this.memberServe.getUserInfo(userId).subscribe(res => {this.user = res});}const wyRememberLogin = this.storageServe.getStorage('wyRememberLogin');if (wyRememberLogin) {this.wyRememberLogin = JSON.parse(wyRememberLogin);}}// 登录onLogin (params: LoginParams) {this.memberServe.login(params).subscribe((user => {this.user = user;this.memberBatchActionsServer.controlModal(false);this.alertMessage('success', '登陆成功');this.storageServe.setStorage({key: 'wyUserId',value: user.profile.userId})this.store$.dispatch(SetUserId({id: user.profile.userId.toString() }));if (params.remember) {this.storageServe.setStorage({key: 'wyRememberLogin',value: JSON.stringify(codeJson(params))})} else {this.storageServe.removeStorage('wyRememberLogin');}}), (error => {this.alertMessage('error', error.message)}));}// 登出onLogout () {this.memberServe.logOut().subscribe(res => {this.user = null;this.storageServe.removeStorage('wyUserId');this.store$.dispatch(SetUserId({id: '' }))this.alertMessage('success', '已退出');}, (error => {this.alertMessage('error', error.message)}));}// 提示信息private alertMessage (type: string, msg: string) {this.message.create(type, msg)}

此时会将登录信息作为参数调用登录API,将返回值存在全局,使用Store将弹框显隐的状态改为false。然后利用nzMessage弹出提示,最后使用封装的localstorage将登录人的ID存入内存。在使用Store将当前登录人的状态ID改写,如果登录时勾选记住密码,将会把表单的内容存入localstorage,如果没勾选将会删除。

member.types.ts

export type User = {level?: number; // 等级listenSongs?: number; // 听歌记录profile: {userId: number, // IDnickname: string, // 昵称avatarUrl: string, // 头像backgroundUrl: string, // 背景图signature: string, // 简介gender: number, // 性别followeds: number, // 粉丝follows: number, // 关注eventCount: number, // 动态};};// 登出返回export interface SampleBack extends AnyJson {code: number;}// 加密数据export interface AnyJson {[key: string]: any;}export type Signin = {code: number;point?: number;msg?: string;}

storage.service.ts

getStorage (key: string, type = 'local'): string {return window[type + 'Storage'].getItem(key)}setStorage (param: AnyJson | AnyJson[], type = 'local') {const kv = Array.isArray(param) ? param : [param];for (const {key, value } of kv) {window[type + 'Storage'].setItem(key, value.toString())}}removeStorage (param: string | string[], type = 'local') {const kv = Array.isArray(param) ? param : [param];for (const item of kv) {window[type + 'Storage'].removeItem(item)}}

主要是封装了set,能够同时将多组的键值对存储。

其实账密存在内存中本身就不对,应该是利用token来检验,所以就当是拓展学习,也利用了base64插件来对账密进行加密和解密。

base64.ts

import {Base64 } from "js-base64";// 加密数据export interface AnyJson {[key: string]: any;}export function codeJson (source: AnyJson, type = 'encode'): AnyJson {const result = {};for (const arr in source) {if (source.hasOwnProperty(arr)) {result[Base64[type](arr)] = Base64[type](source[arr])}}return result;}

总结

有关登录的安全验证还是有点迷惑的,对于token的理解还是不太明确,所以这个还是要好好的功课一下的。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。