This is my first post.
I've just started learning Go and Angular and I'm attempting to connect the angular app to a go api. I've written both and am stuck identifying the root of the problem. I thought it was a CORS problem, but it works fine if I don't include the headers line of code in my Angular http request. At this point I'm just trying to add the header. The authorization code isn't implemented yet.
Both apps are running locally with the Go app on port 5000 and Angular on 4200
Angular http request that doesn't work:
this.http.get<ProjectedBalance>(requestUrl, {headers: new HttpHeaders().set('Authorization', 'my-auth-token')}) .subscribe(data => { this.projBalance = data.projBalance; }
Angular http request that works:
this.http.get<ProjectedBalance>(requestUrl) .subscribe(data => { this.projBalance = data.projBalance; }
I'm getting this error:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403
I'm using the gorilla/mux and gorilla/handlers in my go code
router := mux.NewRouter() router.HandleFunc("/home/{endDate}", GetProjBalance).Methods("GET", "OPTIONS") headersOk := handlers.AllowedHeaders([]string{"X-Requested-With, Content-Type, Authorization"}) originsOk := handlers.AllowedOrigins([]string{"*"}) methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"}) //start server on port log.Fatal(http.ListenAndServe(":5000", handlers.CORS(originsOk, headersOk, methodsOk)(router)))
Headers from Chrome Dev Tools
Request URL:http://localhost:5000/home/2020-12-21 Request Method:OPTIONS Status Code:403 Forbidden Remote Address:[::1]:5000 Referrer Policy:no-referrer-when-downgrade Response Headers view source Content-Length:0 Content-Type:text/plain; charset=utf-8 Date:Mon, 20 Nov 2017 21:39:43 GMT Request Headers view source Accept:*/* Accept-Encoding:gzip, deflate, br Accept-Language:en-US,en;q=0.9,uz;q=0.8 Access-Control-Request-Headers:authorization Access-Control-Request-Method:GET Connection:keep-alive Host:localhost:5000 Origin:http://localhost:4200
It is a simple authentication scheme built into the HTTP protocol. The client sends HTTP requests with the Authorization header that contains the word Basic, followed by a space and a base64-encoded(non-encrypted) string username: password. For example, to authorize as username / Pa$$w0rd the client would send.
To send a GET request with a Bearer Token authorization header, you need to make an HTTP GET request and provide your Bearer Token with the Authorization: Bearer {token} HTTP header.
const ui = SwaggerUIBundle({ ..., requestInterceptor: function (req) { req. headers = { 'Authorization': 'Bearer ' + document. getElementById('bearer-code- input'). value , 'Accept': 'application/json', 'Content-Type': 'application/json' }; return req; }, ... })
Regarding the best way of handling Authentication headers in Angular > 4 it's best to useHttp Interceptors
for adding them to each request, and afterwards usingGuards
for protecting your routes.
Here's a full example of an AuthInterceptor
that I'm using in my app:
auth.interceptor.ts
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { AuthService } from './auth.service'; @Injectable() export class AuthInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { req = req.clone({ setHeaders: { 'Content-Type' : 'application/json; charset=utf-8', 'Accept' : 'application/json', 'Authorization': `Bearer ${AuthService.getToken()}`, }, }); return next.handle(req); } }
You'll need to register your interceptor in the app.module
as a provider:
app.module.ts
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; import { AuthInterceptor } from '../auth/auth.interceptor'; ... imports: [ HttpClientModule, ... ], providers: [ { provide : HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi : true, }, ... ], ...
You can read about this method further in this post.
Regarding the Go's side of things, this is most likely a case of mismatch between
Request Headers you're sending and the headers CORS allow.
First thing you should try is allowing all of them:
headersOk := handlers.AllowedHeaders([]string{"*"}) originsOk := handlers.AllowedOrigins([]string{"*"}) methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
And if the problem goes away try carefully structuring your CORS one by one to what your client is sending.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With