2

I was working on a project that have a separate frontend and backend. I use tsoa-express and express session for my authentication(port 4040) and I create a simple frontend(port 5500) for testing.

Backend:

// Session.ts

class Session {
    public mount(_express: Application): Application {
        _express.set('trust proxy', 1)
        const sess: SessionOptions = {
            secret: Locals.config().appSecret,
            resave: false,
            saveUninitialized: true,
            // rolling: true,
            proxy:true,
            cookie: { 
                maxAge: 3600 * 1000, // 1 hr
                httpOnly: false,
                secure: false,  
                domain: undefined, 
                sameSite: false,
            },  // cookie expire in half an hour from last activity
            store: MongoStore.create({
                mongoUrl: Locals.config().mongooseUrl
            })
        };
        _express.use(session(sess));

        return _express;
    }
}

// authController.ts

@Tags("Authentication")
@Route("auth")
export class AuthController extends Controller {
    @Post("/login")
    @Middlewares([AuthService.login])
    public async login(@Body() body: loginInput): Promise<any> {
        return null;
    }
}

// authService.ts
export class AuthService {
    public async login(req: express.Request, res: express.Response, next: express.NextFunction) : Promise<void> {
        res.header('Access-Control-Allow-Credentials', "true");
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
        res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
        if (req.body.hasOwnProperty("username") && req.body.hasOwnProperty("password")) {

            const user = await User.findOne({login_name: req.body.username});
            if (user) {
                if (bcrypt.compareSync(req.body.password, user.password)){
                    if (!req.session.isAuthenticated){
                        req.session.regenerate(function (err: any) {
                            if (err) throw next(err);
                            req.session.isAuthenticated = true;
                            req.session.user_id = user._id;
                            req.session.session_users = 1;
                            req.session.save(function (err) {if (err) return next(err)})
                        });
                        res.status(200).send({user: user._id, sid: signature.sign(req.sessionID, Locals.config().appSecret)});
                    } else {
                        req.session.session_users = (req.session.session_users) ? req.session.session_users++ : 1;
                        res.status(200).send({user: user._id});
                    }
                    
                } else {
                    res.status(401).send({ reason: "Failed to login.", details: "Invalid password. Please try again." });
                }
            } else {
                res.status(401).send( { reason: "Failed to login.",details: "Invalid username. Please try again." });
            }
        } else {
            next()
        }
    }
}

Frontend html:

<!DOCTYPE html>
<html lang="en">
  <head>
  </head>

  <button id="login-btn">Login button</button>
  <script src="script.js"></script>
</html>

Frontend JS:

const login_button = document.getElementById('login-btn');

const data = {
  "username": "any valid username",
  "password": "any valid pw"
}

login_button.addEventListener('click', async _ => {
  fetch('http://localhost:4040/auth/login', {
    method: 'post',
    mode: 'cors',
    cache: 'default',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(data)
  })
  .then(response => response.json())
  .then(data => {
    console.log(data);
    window.localStorage.setItem('sid', data['sid']);
  })
  .catch(error => {
    console.error(`Error: ${error}`);
  });
});

After I use the login function, My browser get the cookie but it failed to authenticate in the following requests. My login function failed to increase the session_user value and all variables value in req.session is undefined. I am forced to use express-session for backward compatibility. May I know what is the problem of my code and how should I setup the session so that I can access the values properly?

Thomas
  • 41
  • 2

0 Answers0