如何在Spring Security中使用React来创建自定义登录页面

时间:2019-05-26 19:27:59

标签: reactjs spring-boot spring-security

我有一个项目,需要使用带有ReactJs的Spring Data REST。我正在尝试制作一个新的自定义登录页面,该页面将覆盖spring security默认具有的页面。但是,它似乎不起作用,我找到的所有文章似乎也无济于事。

使用带有inMemoryAuthentication的默认登录页面,我能够以管理员和用户身份登录。但是,当我使用自定义登录页面时,单击“提交”将不会发生任何事情。

这是我的代码:

--login.html--

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>

    <!-- necessary -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="/css/structure.css">
</head>

<body class="background-color">

<!-- include navigation bar -->
<div id="navbar"> </div>
<script src="/reactjs/build/navbar.bundle.js"> </script>

<br>
<br>

<!-- login form -->
<div id="loginForm"> </div>
<script src="/reactjs/build/login.bundle.js"> </script>

</body>
</html>
--login.js--

const React = require('react');
const ReactDOM = require('react-dom');
import { Container, Row, Col, Card, Form, ButtonToolbar, Button } from 'react-bootstrap';

class Login extends React.Component {

    constructor(props, context) {
        super(props, context);

        this.state = {
            username: '',
            password: ''
        }

        //binding this to submethods
        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }

    onChange(e){
        this.setState({
            [e.target.name]: e.target.value
        });
    }

    onSubmit(e){
        e.preventDefault();

        fetch(this.props.action, {
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            method: this.props.method,
            body: JSON.stringify({
                username: this.state.username,
                password: this.state.password,
            })
        });

        this.setState({
            username: '',
            password: ''
        });
    }

    render() {
      return(
            <Container>
              <Row>
                <Col md={{ span: 4, offset: 4 }} className="text-center">
                  <Card border="dark">
                    <Card.Header as="h3" className="text-center" style={{backgroundColor: 'LightSkyBlue'}}>Login</Card.Header>
                    <Card.Body>
                      <Card.Title>Join our community!</Card.Title>
                        <Form id="login-form"
                          action={this.props.action}
                          method={this.props.method}
                          onSubmit={this.onSubmit}>

                          <Form.Group controlId="formUsername">
                            <Form.Control type="text" name="username" placeholder="Username" />
                          </Form.Group>

                          <Form.Group controlId="formPassword">
                            <Form.Control type="password" name="password" placeholder="Password" />
                          </Form.Group>

                          <ButtonToolbar size="lg">
                            <Button type="submit" variant="dark" block> Submit </Button>
                          </ButtonToolbar>

                        </Form>
                    </Card.Body>
                  </Card>
                </Col>
              </Row>
            </Container>
      );
    }

}

// App.propTypes = { action: React.PropTypes.string.isRequired, method: React.PropTypes.string}
Login.defaultProps = {
    action: '/login',
    method: 'POST'
};


ReactDOM.render(
    <Login />,
  document.getElementById('loginForm')
)
--spring security configuration--

package com.dit.ebay.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .passwordEncoder(encoder())
            .withUser("admin").password(encoder().encode("admin")).roles("ADMIN")
            .and()
            .withUser("user").password(encoder().encode("user")).roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .defaultSuccessUrl("/welcome")
                    .permitAll()
                    .and()
                .logout()
                    .permitAll();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
                .ignoring()
                .antMatchers("/resources/**", "/static/**", "/css/**", "/reactjs/**", "/pics/**");
    }
}

我创建的登录页面按预期出现。我在做什么错,点击提交后我没有得到预期的结果?

编辑1 新的login.js脚本:

const React = require('react');
const ReactDOM = require('react-dom');
import { Container, Row, Col, Card, Form, ButtonToolbar, Button } from 'react-bootstrap';

class Login extends React.Component {

    constructor(props, context) {
        super(props, context);

        this.state = {
            username: '',
            password: ''
        }

        //binding this to submethods
        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }

    onChange(e){
        this.setState({
            [e.target.name]: e.target.value
        });
    }

    onSubmit(e){
        e.preventDefault();

        console.log("username:" + this.state.username);
        console.log("password:" + this.state.password);
        console.log("action:" + this.props.action);
        console.log("method:" + this.props.method);

        fetch(this.props.action, {
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            method: this.props.method,
            body: JSON.stringify({
                username: this.state.username,
                password: this.state.password
            })
        })
        .then((response) => response.text())
        .then((response) => console.log(response),
              (error) =>  console.log(error)
        );

        this.setState({
            username: '',
            password: ''
        });
    }

    render() {
      return(
            <Container>
              <Row>
                <Col md={{ span: 4, offset: 4 }} className="text-center">
                  <Card border="dark">
                    <Card.Header as="h3" className="text-center" style={{backgroundColor: 'LightSkyBlue'}}>Login</Card.Header>
                    <Card.Body>
                        <Form id="login-form"
                          action={this.props.action}
                          method={this.props.method}
                          onSubmit={this.onSubmit}>

                          <Form.Group controlId="formUsername">
                            <Form.Control type="text" name="username" onChange={this.onChange} placeholder="Username" />
                          </Form.Group>

                          <Form.Group controlId="formPassword">
                            <Form.Control type="password" name="password" onChange={this.onChange} placeholder="Password" />
                          </Form.Group>

                          <ButtonToolbar size="lg">
                            <Button type="submit" variant="dark" block> Submit </Button>
                          </ButtonToolbar>

                        </Form>
                    </Card.Body>
                  </Card>
                </Col>
              </Row>
            </Container>
      );
    }

}

// App.propTypes = { action: React.PropTypes.string.isRequired, method: React.PropTypes.string}
Login.defaultProps = {
    action: 'http://localhost:8080/login',
    method: 'POST'
};


ReactDOM.render(
    <Login />,
  document.getElementById('loginForm')
)

现在,作为回应,我得到了登录页面。这就是为什么我有response.text()而不是response.json()的原因。获取第二个将返回意外的令牌错误,因为响应的格式不是json。

0 个答案:

没有答案