简体   繁体   English

passport.js 不适用于手动表单数据发布请求角度

[英]passport.js not working with manual form-data post request angular

I have created a form in angular, On click of submit button I am hitting a post request with Content-Type header with value application/x-www-form-urlencoded .我已经创建了一个有角度的表单,点击提交按钮时,我点击了一个带有值application/x-www-form-urlencoded Content-Type标头的帖子请求。

onSubmit(user:User) {
    let headers = new Headers();
    // to send data as form data as passport library want it as a form data
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    return this.http.post('/login', user, { headers: headers }).subscribe((data) => {
      console.log("Data : ", data);
    });
} 

and the model user is of type并且模型用户属于

// Class to bind user data
class User {
  constructor(private name: string, private password: string) {
  }
}

Here is the server side code这是服务器端代码

 let userList: User[] = [new User(1, "Sunil"), new User(2, "Sukhi")];

        let app = express();

        // passport library
        let passport = require('passport');
        let LocalStrategy = require('passport-local').Strategy;

        // middlewares
        app.use(express.static("public"));
        app.use(bodyParser.json());
        app.use(bodyParser.urlencoded({ extended: false }));
        app.use(session({ resave: false, saveUninitialized: true, secret: "secretKey123!!" }));

        // passport middleware invoked on every request to ensure session contains passport.user object
        app.use(passport.initialize());

        // load seriliazed session user object to req.user 
        app.use(passport.session());

        // Only during the authentication to specify what user information should be stored in the session.
        passport.serializeUser(function (user, done) {
            console.log("Serializer : ", user)
            done(null, user.userId);
        });

        // Invoked on every request by passport.session
        passport.deserializeUser(function (userId, done) {
            let user = userList.filter(user => userId === user.userId);
            console.log("D-serializer : ", user);
            // only pass if user exist in the session
            if (user.length) {
                done(null, user[0]);
            }
        });
// passport strategy : Only invoked on the route which uses the passport.authenticate middleware.
        passport.use(new LocalStrategy({
            usernameField: 'name',
            passwordField: 'password'
        },
            function (username, password, done) {
                console.log("Strategy : Authenticating if user is valid  :", username)
                let user = userList.filter(user => username === user.userName);
                console.log("Valid user : ",user)
                if (!user) {
                    return done(null, false, { message: 'Incorrect username.' });
                }
                return done(null, user[0]);
            }
));

app.post('/login', passport.authenticate('local', {
     successRedirect: '/done',
     failureRedirect: '/login'
}));
app.get('/done', function (req, res) {
     console.log("Done")
     res.send(req.session)
})


app.get('/login', function (req, res) {
     console.log("login")
     res.send("login")
})

but every time it is returning login但每次返回登录时

In my case, the issue was with the request body.就我而言,问题出在请求正文上。 I was sending the user object directly so this was not working.我直接发送用户对象,所以这不起作用。 To solve this I have created the body object using URLSearchParams .为了解决这个问题,我使用URLSearchParams创建了 body 对象。

let  body = new URLSearchParams();
body.append('name', this.user.name);
body.append('password', this.user.password); 

Here is the onSubmit method这是onSubmit方法

onSubmit() {
    let  body = new URLSearchParams();
    body.append('name', this.user.name);
    body.append('password', this.user.password);

    let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded'});
    let options = new RequestOptions({headers});

    this.http.post("/services/login", body.toString(), options).subscribe((response)=>{
        let arrUrl = response.url.split("/");
        let url = "/" + arrUrl[arrUrl.length-1];
        this.router.navigate([url]);
    });
}

Second, from the login form, I was not passing the value for password field.其次,从登录表单中,我没有传递password字段的值。 So the local strategy's callback(with username and password) was not getting called.所以本地策略的回调(使用用户名和密码)没有被调用。

If you don't pass any of the fields then the callback method will not be called and will redirect to the failureRedirect URL.如果您不传递任何字段,则不会调用回调方法并将重定向到failureRedirect URL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM