我用json网络令牌保护了我的api。如何将其连接到我的角度应用程序。应用程序中将没有登录和注册。
我在Google,youtube和stackoverflow上做了很多研究。但是我从未找到想要的结果。
我只想向进入网站的人显示数据。我不希望网站外的任何人访问Json文件。
这是我的express.js
const app = require('express')()
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const fs = require('fs')
const jwt = require('jsonwebtoken')
const PORT = 3002
app.use(cors())
app.use(bodyParser.json())
app.get('/', (req, res) => {
res.json({message: 'Api'})
})
app.post('/api/login',(req, res)=> {
const user = { id: 3 }
const token = jwt.sign({ user }, 'our_key')
res.json({
token: token
})
})
app.get('/api/protected', ensureToken,(req, res)=> {
jwt.verify(req.token, 'our_key',function (err, data) {
if (err) {
res.sendStatus(403)
} else {
fs.readFile('data.json','utf-8',(err,data)=>{
res.setHeader("Content-Type", "application/json; charset=utf-8")
data = JSON.parse(data)
console.log(data)
res.end(JSON.stringify(data,null,4))
})
}
})
})
function ensureToken(req, res, next) {
const bearerHeader = req.headers["authorization"]
if (typeof bearerHeader !== 'undefined') {
const bearer = bearerHeader.split(" ")
const bearerToken = bearer[1]
req.token = bearerToken
next()
} else {
res.sendStatus(403)
}
}
app.listen(PORT, function(){
console.log('Server http://localhost:'+ PORT + ' OK')
})
angular和jwt通过登录/注册系统连接。没有这个,我们可以做到吗?
答案 0 :(得分:0)
在这种情况下,我看到的唯一解决方案是以下解决方案(老实说,它并非100%安全)
您应该在后端做的第一件事是:
app.use(cors({
origin: 'http://yourapp.com'
}));
将cors限制为其他域。
角度一侧的第二部分是使令牌工作并与拦截器一侧的后端通信。
查看代码后,它应如下所示:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Stackoverflow - Test</title>
<base href="/" />
</head>
<body>
<app-root></app-root>
</body>
</html>
appModule.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptor } from './data.service';
import { RouterModule, ROUTES } from '@angular/router';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
],
providers: [ {
provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptor,
multi: true,
}],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts
import { Component, OnInit } from '@angular/core';
import { User } from './data.model';
import { Value } from './data.model';
import { HttpClient } from '@angular/common/http'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
users:User[];
constructor(private _http: HttpClient){}
ngOnInit(){
this.loadData();
}
public async getToken(): Promise<void> {
console.log('try to get token from api');
const result: any = await this._http
.get(`http://localhost:3002/api/login`)
.toPromise();
localStorage.setItem('userToken', result.token);
}
private async loadData(): Promise<void> {
if (localStorage.getItem('userToken') == null) {
await this.getToken();
}
const result = await this._http.get(`http://localhost:3002/api/protected`)
.toPromise();
console.log(result);
}
}
和您的data.service.ts(通常为此目的应命名为token.interceptor.ts或类似的名称。
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
HttpClient
} from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { User } from './data.model';
import {map, switchMap} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class TokenInterceptor implements HttpInterceptor {
constructor(private _http: HttpClient) {}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
let currentToken =
localStorage.getItem('userToken') ||
sessionStorage.getItem('userToken');
const authReq = request.clone({
setHeaders: {
Authorization: 'Bearer ' + currentToken || []
}
});
return next.handle(authReq);
}
}