I try these code to connect my ionic app to apiserver (get)
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class EncryptionService {
url = 'https://api.am....com';
api-key='......'
constructor(private http: HttpClient) { }
newcheck(checkid: string ,cost: string,toname: string,tocode: string,passcode: string,date: string,checkfor: string,back: string): {
return this.http.get(`${this.url}?key=${this.api-key}&checkid=${encodeURI(checkid)}`);
}
}
my API has API key and get data in URL
how can i perform these in the secured way?
for example to prevent someone to listen and monitor transferred data between app and server?
prevent someone to distract and fake received data by app?
or, anything to make this connection secured
It looks like you're already using https which is encrypted.
A man in the middle attack should be prevented by default since browsers verify the certificate chain automatically.
I recommend reading this guide about https.
Related
In my angular application I have interceptor class like that:
import { Injectable, Inject, Optional, PLATFORM_ID } from '#angular/core';
import {
HttpInterceptor,
HttpHandler,
HttpRequest,
} from '#angular/common/http';
import { REQUEST } from '#nguniversal/express-engine/tokens';
import { isPlatformServer } from '#angular/common';
#Injectable()
export class UniversalInterceptor implements HttpInterceptor {
constructor(
#Inject(PLATFORM_ID) private platformId,
#Optional() #Inject(REQUEST) private request
) {}
intercept(req: HttpRequest<any>, next: HttpHandler) {
if (isPlatformServer(this.platformId)) {
req = req.clone({ headers: req.headers.set('Cookie', this.request.headers.cookie) });
}
return next.handle(req);
}
}
I am using Angular Universal server side rendering, so I take token from server and manually set in every API call which will be called by server. Everything works fine, but is it safe? I set token cookie manually inside every API request's header, maybe that's somehow risky?
I mayb be wrong, but I think it only matters if you send cookies to an API that you don't own, in which case you might be sending sensitive information to a 3rd party.
If you don't own the API, you could try parsing the cookies string (this.request.headers.cookie) and only pass the ones that the API need
I am building an application using Angular 7, I have handled the API calls, the JWT Token authentication system using C#, and also updating the LocalStorage() when necessary, when the user logs in and logs out, and all these are working perfectly.
My problem is I want it to run a login check as a middleware within the application rather than on the lifecycle method - ng.onInit(). How do I go about this?
Is there a way to execute lifecycle events as an entry component or service. That is, before any component loads it is able to check if the user is logged in or not and redirect via Router to a desired page.
Guard is based on the routes... so I think you should prefer a module/service solution.
import { APP_INITIALIZER } from '#angular/core';
then add it as a provider like this :
export function initApp(initService: YourInitService) {
return () => {
initService.Init();
}
}
{ provide: APP_INITIALIZER,useFactory: initApp, deps: [YourInitService], multi: true }
Routing Decisions Based on Token Expiration
If you’re using JSON Web Tokens (JWT) to secure your Angular app (and I recommend that you do), one way to make a decision about whether or not a route should be accessed is to check the token’s expiration time. It’s likely that you’re using the JWT to let your users access protected resources on your backend. If this is the case, the token won’t be useful if it is expired, so this is a good indication that the user should be considered “not authenticated”.
Create a method in your authentication service which checks whether or not the user is authenticated. Again, for the purposes of stateless authentication with JWT, that is simply a matter of whether the token is expired. The JwtHelperService class from angular2-jwt can be used for this.
// src/app/auth/auth.service.ts
import { Injectable } from '#angular/core';
import { JwtHelperService } from '#auth0/angular-jwt';
#Injectable()
export class AuthService {
constructor(public jwtHelper: JwtHelperService) {}
// ...
public isAuthenticated(): boolean {
const token = localStorage.getItem('token');
// Check whether the token is expired and return
// true or false
return !this.jwtHelper.isTokenExpired(token);
}
}
Note: This example assumes that you are storing the user’s JWT in local storage.
Create a new service which implements the route guard. You can call it whatever you like, but something like auth-guard.service is generally sufficient.
// src/app/auth/auth-guard.service.ts
import { Injectable } from '#angular/core';
import { Router, CanActivate } from '#angular/router';
import { AuthService } from './auth.service';
#Injectable()
export class AuthGuardService implements CanActivate {
constructor(public auth: AuthService, public router: Router) {}
canActivate(): boolean {
if (!this.auth.isAuthenticated()) {
this.router.navigate(['login']);
return false;
}
return true;
}
}
The service injects AuthService and Router and has a single method called canActivate. This method is necessary to properly implement the CanActivate interface.
The canActivate method returns a boolean indicating whether or not navigation to a route should be allowed. If the user isn’t authenticated, they are re-routed to some other place, in this case a route called /login.
Now the guard can be applied to any routes you wish to protect.
// src/app/app.routes.ts
import { Routes, CanActivate } from '#angular/router';
import { ProfileComponent } from './profile/profile.component';
import {
AuthGuardService as AuthGuard
} from './auth/auth-guard.service';
export const ROUTES: Routes = [
{ path: '', component: HomeComponent },
{
path: 'profile',
component: ProfileComponent,
canActivate: [AuthGuard]
},
{ path: '**', redirectTo: '' }
];
The /profile route has an extra config value now: canActivate. The AuthGuard that was created above is passed to an array for canActivate which means it will be run any time someone tries to access the /profile route. If the user is authenticated, they get to the route. If not, they are redirected to the /login route.
Note: The canActivate guard still allows the component for a given route to be activated (but not navigated to). If we wanted to prevent activation altogether, we could use the canLoad guard.
more info here
You should check for Guard in angular, especially canActivate Guard: https://angular.io/guide/router
A guard is created like this:
#Injectable({
providedIn: 'root'
})
export class MyGuard implements CanLoad {
constructor() {}
canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> |
Promise<boolean> | boolean {
const x = true;
if (x) {
return true; // It allows access to the route;
} else {
// redirect where you want;
return false; // it doesnt allow to access to the route
}
}
}
Then in your routing Module:
{
path: "yourRoute",
canActivate: [MyGuard],
component: YourComponent
}
For authentication, you have a good library that uses guard here:
https://www.npmjs.com/package/ngx-auth
You should implement an authGuardService or something like that to use as middleware for your routing (using the canActivate section)
See: https://angular.io/api/router/CanActivate
This prevents routes from being loaded if the canActivate fails the condition (which is preferred when using a login system etc instead of checking in lifecycle hooks).
I have a service which is defined like this:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable, of, Subscription, combineLatest } from 'rxjs';
import { map, catchError, retry } from 'rxjs/operators';
#Injectable({
providedIn: 'root',
})
export class MyDataService {
constructor(private http: HttpClient) {
console.log('Called MyDataService constructor');
}
}
As far as I understand this service should be singleton throughout the runtime of the apllication.
Now, when the page refreshes, it logs "Called DataService constructor" correctly.
Unfortunately when I navigate to another page (new routes with lazy loading modules) the constructor is run again and it logs "Called DataService constructor" on each route change.
Did I miss something?
providedIn: 'root' means that it will only be instantiated once and the same instance will be provided to all dependency requests. If you are see the constructor run more than once then you are providing it somewhere else. Search for where you are providing it as providedIn: 'root' does not need to be listed in a provides list. Search for "provides : [" and see what is providing the MyDataService and remove it. If you are using VS Code you can right click on the class name and select find all references and see where it is in a provides array.
My question sounds similar to Cannot find the '#angular/common/http' module and Error loading #angular/common/http - angular 2 but the problem is a bit different:
I am using Angular 4.3.5 and I am trying to read data from a Web API. (This API puts out JSON data and is using SignalR and .net Core).
I have followed several tutorials and came up with this code for the class that will actually contact the service:
import 'rxjs/add/operator/map';
import { HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { Configuration } from './Configuration.js';
#Injectable()
export class DataService {
private actionUrl: string;
constructor(private http: HttpClient, private configuration: Configuration) {
this.actionUrl = configuration.serviceUrl;
}
//public getAll<T>(): Observable<T> {
// return this.http.get<T>(this.actionUrl);
//}
public getSingle<T>(id: number): Observable<T> {
return this.http.get<T>(this.actionUrl + id);
}
}
#Injectable()
export class CustomInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!req.headers.has('Content-Type')) {
req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
}
req = req.clone({ headers: req.headers.set('Accept', 'application/json') });
console.log(JSON.stringify(req.headers));
return next.handle(req);
}
}
Now, building this project (I am using Visual Studio 2017 Enterprise) and running a gulp task to transpile the .ts to .js works just fine, so do all the intellisense-tooltips - the IDE does recognize the existance of those things.
But if I open it up in a browser (doesnt matter if firefox, edge or chrome) I get the following error:
zone.js:958 GET http://localhost:3966/libs/#angular/common/bundles/common.umd.js/http 404 (Not Found)
If I edit the transpiled javascript file by hand and write common-http.umd.js there, the file is found. (This is the reason why at the top I import Configuration.js instead of Configuration - it doesnt seem to want to automatically resolve the suffix, like in some tutorials).
I hope I am not too vague, since this is my first Time asking something publically. Also I was not able to find an answer in the given questions.
Well, I found a solution, for anybody who is curious why this and similar problems exist:
I had to edit my systemjs file and add this line:
'#angular/common/http': 'npm:#angular/common/bundles/common-http.umd.js',
and it works!
I've been stuck on an error that I'm not completely sure how to solve.
My application is made in Angular2 and runs completely in a webworker largely based on this tutorial http://www.syntaxsuccess.com/viewarticle/web-workers-in-angular-2.0
My first feature was an implementation of socket.io which is working perfectly(also with observables etc..) but now I want to use the Http service of Angular2 and I get the following error:
My code of the service is like this and the error arrises when I call validateAccessToken (I have to add the .js on my imports otherwise I get a 404 on the files within the webworker):
import { Injectable } from '#angular/core';
import { Http, Headers, RequestOptions, Response } from "#angular/http";
import { environment } from "../../../environments/environment.js";
import { Observable } from "rxjs/Observable.js";
import 'rxjs/add/operator/toPromise.js';
import 'rxjs/add/operator/map.js';
#Injectable()
export class AuthService {
headers: Headers;
options: RequestOptions;
url: string;
constructor(private http:Http) {
this.url = environment.authServerUrl;
}
validateAccessToken(token) {
return this.http.get(this.url)
.map(this.extractData)
.catch(this.handleError);
};
extractData(response: Response) {...}
handleError(error: any) {...}
}
I know the question is quite vague but with the information I get from the error it's not really clear what's going wrong for me.
The CookieXSRFStrategy is default enabled by Angular2 and used by http.
The webworker does not have DOM access to get the cookie to insert in the http headers. And thus throws the error Uncaught not implemented.
You should implement your own CookieXSRFStrategy strategy which at least does not throw this error ;)