Streamlined Authorization in MEAN (SPA) Applications

I have created an application, but now I am trying to adapt it into a SPA application. The main issue I am facing is with the Authorization process.

While I can successfully register new users, log them in, and retrieve their tokens, I seem to encounter an error when attempting to validate the token in my middleware. I suspect there might be something wrong within step 3 (as steps 1-2 are functioning correctly), however, I have included all steps along with the relevant code for each step.

Could someone please assist me in identifying what I may be doing incorrectly?

1> Registering a new account (storing the account in the DB)

Backend:

router.post("/register", function(req, res){
CreateUser(req.body.username, req.body.password, 0, function(err, nwUser){
    if(err){
        console.log('error: ');
        return res.redirect("register"); //TODO: show the error message in 'err'
    }
        passport.authenticate("local")(req, res, function(){
            console.log('success, going to try to create a token:');
            //secret key,TODO: set in variable (or better environment)
            const token = jwt.sign(nwUser.toJSON(), "SECRETCODE");
            const result = res.json({nwUser, token});
            return result;
        });
    });
});

2> Logging in to an account (if successful, sending an encrypted token to the Client (Angular))

Backend:

router.post('/login',passport.authenticate('local'), function(req, res) {
    User.findById(req.user._id, function(err, foundUser){
        if(err){
            console.log('Error with logging in!');
            console.log(err);
            return err;
        }
        const token = jwt.sign(foundUser.toJSON(), "SECRETCODE");
        const result = res.json({foundUser, token});
        return result;
    });
});

3> If a request now requires authorization, the client(Angular) should also send the token with the request and the backend checks if the token is valid (inside the middleware). If so, the data is returned.

How I send the data from Angular:

const headers: HttpHeaders = new HttpHeaders();
headers.append('Authorization', 'Bearer ' + this.authService.getToken());

console.log('token before sending in data-storage: ' + this.authService.getToken());
this.httpClient.get<Category[]>(environment.backendServer + '/categories/',
  {observe: 'body', responseType: 'json', headers: headers}).pipe(map(
  (categories) => {
    console.log(categories);
    return categories;
  }
)).subscribe(
  (categories: Category[]) => {
    this.categoryService.setCategories(categories);
  }
);

Middleware used on the backend:

middlewareObj.authenticateJWT = function(req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
//token = undefined????

// decode token
if (token) {

    // verifies secret and checks exp
    jwt.verify(token, app.get('SECRETCODE'), function(err, decoded) {
        if (err) {
            return res.json({ success: false, message: 'Failed to authenticate token.' });
        } else {
            // if everything is good, save to request for use in other routes
            req.decoded = decoded;
            next();
        }
    });

} else {

    // if there is no token
    // return an error
    return res.status(403).send({
        success: false,
        message: 'No token provided.'
    });

}
}

So far I have managed to complete steps 1-2, although there may be areas that could be optimized. However, I am currently stuck on step 3...

I am unsure of how to properly send the token from Angular to the backend.

Answer №1

It appears that the header you are using does not match the token being used.

Instead of searching for

req.headers['x-access-token']

try

req.headers['Authorization']

since this is what you added to your header. If you are sending from the client side, send JSON like this:

{token: this.authService.getToken()}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using Angular and nativeElement.style: how to alter cursor appearance when clicked and pressed (down state)

I am working with a native elementRef CODE: this.eleRef.nativeElement.style = "_____?????_____" What should go in "???" in order to apply the :active style to the element? (I want to change the cursor style when the mouse is clicked down, not when it is ...

The argument type 'MatSort | null' cannot be assigned to the parameter type 'MatSort' in this scenario

When attempting to retrieve sorted data from MatTableDataSource, I used the following code: this.source = this.dataSource.sortData(this.dataSource.filteredData,this.dataSource.sort); Unfortunately, I encountered an error message: Argument of type ' ...

Can Angular 9 be used to compile a latex document?

Is it possible to utilize Angular 9 to compile and generate PDF files using latex? Specifically, I am curious about how to compile a document using Angular and Pdflatex. The idea is for the client to input their data in the form of a JSON data structure ...

Using `await` inside an if block does not change the type of this expression

Within my code, I have an array containing different user names. My goal is to loop through each name, verify if the user exists in the database, and then create the user if necessary. However, my linter keeps flagging a message stating 'await' h ...

Accessing route parameters in Angular directly from the templateFinding route parameters in

There are times when my routes have multiple parameters like: /checklists/:type/:view/:filter I want to generate links in the template in this manner: <a routerLink="['/checklists',':type',':view',':filter']"> ...

What is the most effective method for comparing two arrays of objects and extracting the differing values within a React application?

I am currently working on implementing a changelog feature for my website. Let's consider the initial array as initArray: [ { "id": 1, "val1": "2023-08-28", "val2": 1, " ...

Handling authentication errors in Angular 2 using @ngrx/effects

Everything is functioning smoothly with @ngrx/store and effects, but now I'm realizing that there will be a significant number of API calls (in effects). If any of those calls returns a 401 error, I need to redirect the user to the login page. The dil ...

Unexpected Data Displayed by Material UI Modal Component

I'm currently facing an issue with my Material UI Modal component in a React/Typescript project. When a card element is clicked on the site, it should display expanded information in a modal view. However, clicking on any card only shows the most rece ...

Angular 8: Issue with PatchValue in Conjunction with ChangeDetector and UpdateValue

I am puzzled by the fact that PatchValue does not seem to work properly with FormBuilder. While it shows data when retrieving the value, it fails to set it in the FormBuilder. Does anyone have an idea why this might be happening? I am utilizing UpdateValue ...

An error occurred while trying to upload the image: Undefined property 'subscribe' cannot be read

Recently, I implemented a create post function that allows users to fill in the title, content, and upload an image. However, I encountered an issue where the progress bar fills up and the image gets uploaded to Firebase successfully, but it doesn't a ...

Experiencing the error "f.ngOnChanges is not a function in target es5" while using Angular4

Encountering an issue f.ngOnChanges is throwing an error The problem arises when my tsconfig.json file is configured to target es5. However, everything works fine if I set the target to es6. Is there a way to make ngOnChange function properly with es ...

Tips for removing the download prompt in Firefox when using Selenium in Typescript

While attempting to download a file in Firefox, a download dialog box pops up. I am looking to disable the download dialog box specifically for zip files so that they are downloaded automatically. Despite trying various preferences settings, the dialog box ...

The Ionic 5 app features a white iframe that functions perfectly on the web platform

Whenever I run my web application's function, the iframe is displayed. However, on Android, all I see is a white screen. Can anyone assist with resolving this issue? HMTL html <ion-content> <ion-button expand="full" color="warning" (clic ...

Typeahead functionality in Angular UI Bootstrap that uses object properties to search and display

I have a similar item (recreation of Map): $scope.vehicles = { 1:{id:1, model:'Coupe'}, 2:{id:2, model:'Truck'}, 3:{id:3, model:'Hatchback'} } I want to utilize the property values in typeahead of ui bootstrap (whil ...

Exploring the capabilities of TypeScript in conjunction with the useRoute function on React Navigation version

When using useRoute, I am attempting to extract the parameters like this: const route = useRoute(); const { params } = route; const { id, name, } = params; Although everything is functioning correctly, the linter is pointing out that id and na ...

What is the TypeScript syntax for indicating multiple generic types for a variable?

Currently working on transitioning one of my projects from JavaScript to TypeScript, however I've hit a roadblock when it comes to type annotation. I have an interface called Serializer and a class that merges these interfaces as shown below: interfa ...

Having difficulty casting the parameter type from Array.find() in TypeScript

In my codebase, I am dealing with the OrganisationInterface type: export declare interface OrganisationInterface { documents?: { [documentType: OrganisationDocumentTypesList]: { // enum id: string; name: string; ...

Chess.js TypeScript declaration file for easy implementation

Currently, I am delving into learning typescript and have taken up the challenge of crafting a declaration file for the chess.js library. However, it seems that I am struggling to grasp the concept of creating one. Whenever I attempt to import the library ...

The specified type cannot be assigned to the type 'IntrinsicAttributes & MoralisProviderProps'

I'm brand new to TypeScript and I have a question about setting initializeOnMount to true. Why does it only allow me to set it to false? Here is the error message: Type '{ children: Element; appId: string | undefined; serverUrl: string | undefine ...

Tips for troubleshooting an Angular error when no specific information is provided

I'm encountering an error `ERROR Error: "[object Object]" in my console and my app is displaying a white screen. Everything was working perfectly fine before, and I can't pinpoint any changes that may have caused this issue. The error appears to ...