我正在使用 Node.js 和 Express 来处理 JWT 身份验证。首先,每次创建和验证用户时,我都会存储一个refresh token内部User集合:
const refreshToken = await jwt.sign({ userId: decoded.user }, process.env.JWT_Refresh_Key);
const user = await User.updateOne({ _id: mongoose.Types.ObjectId(decoded.user) }, { refresh_token: refreshToken, status: true });Run Code Online (Sandbox Code Playgroud)
成功登录后生成 JWT 访问令牌(15 分钟后过期):
const token = await jwt.sign(
{ email: user.email, userId: user._id, role: user.role },
process.env.JWT_Key,
{ expiresIn: '15m' });
res.status(200).json({success: true, token: token});Run Code Online (Sandbox Code Playgroud)
然后access token存储在localStorage由 Angular Http Interceptor 和 auth 方法处理。15分钟后,token处理请求将无效,所以我需要使用refresh token存储在数据库中的。
正在调用刷新方法AuthService.ts …
这是AuthInterceptor:
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const Token = this.authService.getToken();
if (!Token) {
return next.handle(req);
}
// Refresh Token first
if (Token.expiresRefreshToken && Number(Token.expiresRefreshToken) < Date.now()) {
this.authService.refreshTokenRefresh(Token.tokenref)
.subscribe((response) => {
localStorage.setItem('tokenref', response.tokenref);
localStorage.setItem('tokenrefexp', response.tokenrefexp);
});
}
// Then next Access Token
if (Token.expiresToken && Number(Token.expiresToken) < Date.now()) {
this.authService.refreshToken(Token.tokenref)
.subscribe((response) => {
localStorage.setItem('token', response.token);
localStorage.setItem('tokenexp', response.tokenexp);
});
}
// Original request with updated custom …Run Code Online (Sandbox Code Playgroud)javascript rxjs typescript angular-http-interceptors angular
我正在尝试订阅服务内的可观察对象。但是,我需要用于AlertService显示错误。一个服务包含另一个服务(循环依赖?)。
这是警报服务
@Injectable()
export class AlertService {
private subject = new Subject<any>();
private keepAfterNavigationChange = false;
constructor(private router: Router) {
// clear alert message on route change
router.events.subscribe(event => {
if (event instanceof NavigationStart) {
if (this.keepAfterNavigationChange) {
// only keep for a single location change
this.keepAfterNavigationChange = false;
} else {
// clear alert
this.subject.next();
}
}
});
}
success(message: string, keepAfterNavigationChange = false) {
this.keepAfterNavigationChange = keepAfterNavigationChange;
this.subject.next({ type: 'success', text: message });
}
error(message: string, …Run Code Online (Sandbox Code Playgroud)我正在使用Angular RxJs subscribe进行HttpClient通话,然后使用第一个通话中的值进行另一个通话。在这种情况下,有一个调用get address object,然后我使用该对象进行了调用。像这样:
@Injectable()
export class AddressService {
constructor(private http: HttpClient) { }
getById(addressId: string, userId: string) {
return this.http.get(BACKEND_URL + 'getAddressById/' + [addressId, userId]);
}
}
export class AddressModalComponent implements OnInit {
constructor(private alertService: AlertService, private addressService: AddressService, @Inject(MAT_DIALOG_DATA) public data: any, private dropdownService: DropdownService)
ngOnInit() {
this.addressService.getById(this.data.id, this.data.userId)
.subscribe(
(address: Address) => {
this.dropdownService.getCidadesBrByEstado(address.name)
.subscribe((cities: BrCity[]) => {
this.cities = cities;
this.address = address;
},
error => console.log(error));
}, error => { …Run Code Online (Sandbox Code Playgroud)这是我的表单组。我在另一个表单组中使用表单组:
this.shopGroup = this.fb.group({
_user: [''],
name: ['', Validators.compose([Validators.required, Validators.maxLength(60)])],
url_name: [''],
desc: ['', Validators.compose([Validators.required, Validators.maxLength(600)])],
photos: [''],
currency: ['Real'],
language: ['Português do Brasil'],
address: this.fb.group({
zipcode: ['', Validators.compose([Validators.required, Validators.pattern('[0-9]{5}[\-]?[0-9]{3}')])],
street: ['', Validators.compose([Validators.required, Validators.maxLength(70)])],
number: [null, Validators.compose([Validators.required, Validators.max(99999)])],
complement: ['', Validators.maxLength(30)],
district: ['', Validators.compose([Validators.required, Validators.maxLength(60)])],
state: ['', Validators.required],
city: ['', Validators.compose([Validators.required, Validators.maxLength(70)])]
}),
status: [true],
created_at: [new Date()],
updated_at: [new Date()]
});
Run Code Online (Sandbox Code Playgroud)
这是模板:
<form [formGroup]="shopGroup">
<mat-horizontal-stepper [linear]="isLinear" #stepper>
// Im not sure how to set stepControl
<mat-step [stepControl]="?">
<ng-template matStepLabel>Store …Run Code Online (Sandbox Code Playgroud) javascript typescript angular-material2 angular angular-material-stepper
我有一个products需要按Product._shop_id.
export class Product {
_id: string;
_shop_id: string;
}
export class Variant { variant_id: string; }
export interface ShoppingCart {
Variant: Variant;
Product: Product;
quantity: number;
totalPrice: number;
}
export class CartComponent implements OnInit {
products: ShoppingCart[] = [];
ngOnInit(){
this.products = [
{Variant: {variant_id: '1'}, Product: {_id: '1', _shop_id:'1'}, quantity: 5, totalPrice: 600},
{Variant: {variant_id: '2'}, Product: {_id: '2', _shop_id:'2'}, quantity: 4, totalPrice: 500},
{Variant: {variant_id: '5'}, Product: {_id: '3', _shop_id:'2'}, quantity: 3, totalPrice: …Run Code Online (Sandbox Code Playgroud)这是我的表单组:
this.shopGroup = this.fb.group({
_user: [''],
name: ['', Validators.compose([Validators.required, Validators.maxLength(60)])],
url_name: [''],
desc: ['', Validators.compose([Validators.required, Validators.maxLength(600)])],
photos: [''],
currency: ['Real'],
language: ['Português do Brasil'],
address: this.fb.group({
zipcode: ['', Validators.compose([Validators.required, Validators.pattern('[0-9]{5}[\-]?[0-9]{3}')])],
street: ['', Validators.compose([Validators.required, Validators.maxLength(70)])],
number: [null, Validators.compose([Validators.required, Validators.max(99999)])],
complement: ['', Validators.maxLength(30)],
district: ['', Validators.compose([Validators.required, Validators.maxLength(60)])],
state: ['', Validators.required],
city: ['', Validators.compose([Validators.required, Validators.maxLength(70)])]
}),
status: [true],
created_at: [new Date()],
updated_at: [new Date()]
});
Run Code Online (Sandbox Code Playgroud)
我需要将它转换为 FormData 因为我正在将图像上传到服务器(Multer 包),但是,我不确定如何address像shopGroup表单数据中的新对象一样处理组。这是我从 FormGroup 转换为 FormData 的操作(地址不起作用):
const shopData: any = new FormData(); …Run Code Online (Sandbox Code Playgroud) 这是我的表格组:
this.productGroup = this.fb.group({
name: ['', Validators.compose([Validators.required, Validators.maxLength(80)])],
variants: this.fb.array([
this.fb.group({
type: '',
options: this.fb.array([])
})
])
});
Run Code Online (Sandbox Code Playgroud)
如何将字符串数组传递给options?像这样[ 'string1', 'string2' ]。我在这里动态获取这些值:stackblitz,但是我不确定如何填充数组。我想将通用字符串数组直接传递给options.
variants数组示例:
variants: [
{ type: 'Color', options: ['Red', 'Blue'] },
{ type: 'Size', options: ['Small', 'Medium', 'Big'] }
]
Run Code Online (Sandbox Code Playgroud)
网页:
<form [formGroup]="productGroup">
<input formControlName="name">
<div formArrayName="variants" *ngFor="let item of productGroup.controls['variants'].controls; let i = index;">
<div [formGroupName]="i">
<mat-form-field>
<input type="text" placeholder="Variable Type" aria-label="Number" matInput formControlName="type" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let …Run Code Online (Sandbox Code Playgroud) angular ×8
typescript ×7
javascript ×6
arrays ×2
rxjs ×2
forms ×1
jwt ×1
node.js ×1
observable ×1