Skip to content

Commit 8f6136b

Browse files
committed
* minor changes
* logout link in dashboard
1 parent 5871324 commit 8f6136b

File tree

8 files changed

+84
-20
lines changed

8 files changed

+84
-20
lines changed

app/public/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
work correctly both with client-side routing and a non-root public URL.
2323
Learn how to configure a non-root public URL by running `npm run build`.
2424
-->
25-
<title>React App</title>
25+
<title>Starter Kit</title>
2626
</head>
2727
<body>
2828
<noscript>You need to enable JavaScript to run this app.</noscript>

app/src/App.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, {Component} from 'react';
22
import {BrowserRouter as Router, Route} from "react-router-dom";
3+
import AuthService from './services/AuthService/AuthService';
34
import LoginPage from './components/LoginPage/LoginPage';
45
import DashboardPage from './components/DashboardPage/DashboardPage';
56

@@ -13,8 +14,16 @@ class App extends Component {
1314
}
1415
}
1516

17+
componentDidMount() {
18+
AuthService.me(data => {
19+
if (data.authenticated) {
20+
this.successfulAuthenticationHandler(data);
21+
}
22+
});
23+
}
24+
1625
successfulAuthenticationHandler = (response) => {
17-
const data = response.data.principal;
26+
const data = response.principal;
1827
const roles = data.authorities.reduce((last, cur) => {
1928
last.push(cur.role);
2029
return last;
@@ -27,17 +36,25 @@ class App extends Component {
2736
});
2837
};
2938

39+
successfulLogoutHandler = () => this.setState({user: null});
40+
3041
render() {
42+
const loginRender = (props) => <LoginPage {...props}
43+
onLoginSuccess={this.successfulAuthenticationHandler}
44+
user={this.state.user}/>;
45+
const dashboardRender = (props) => <DashboardPage {...props}
46+
onLogoutSuccess={this.successfulLogoutHandler}
47+
user={this.state.user}/>;
3148
return (
3249
<Router>
3350
<div>
3451
<Route path='/'
3552
exact
36-
render={(props) => <LoginPage {...props}
37-
onLoginSuccess={this.successfulAuthenticationHandler}
38-
user={this.state.user}/>}/>
53+
render={(p) => this.state.user ? dashboardRender(p) : loginRender(p)}/>
54+
<Route path='/login'
55+
render={loginRender}/>
3956
<Route path='/dashboard/'
40-
render={(props) => <DashboardPage {...props} user={this.state.user}/>}/>
57+
render={dashboardRender}/>
4158
</div>
4259
</Router>
4360
);

app/src/components/DashboardPage/DashboardPage.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import {Redirect} from 'react-router-dom';
3+
import AuthService from '../../services/AuthService/AuthService';
34

45
const dashboardPage = (props) => {
56
if (!props.user) {
@@ -15,6 +16,10 @@ const dashboardPage = (props) => {
1516
<div className="col">
1617
<h1>Hello, {props.user.name}!</h1>
1718
{specializedParagraph}
19+
<a href="/" onClick={(evt) => {
20+
evt.preventDefault();
21+
AuthService.logout(props.onLogoutSuccess)
22+
}}>Logout</a>
1823
</div>
1924
</div>
2025
);

app/src/components/LoginPage/LoginPage.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import styles from './LoginPage.module.css';
33
import logo from '../../logo.svg';
44
import {Alert} from 'reactstrap';
55
import PropTypes from 'prop-types';
6-
import axios from 'axios';
6+
import AuthService from '../../services/AuthService/AuthService';
77
import {Redirect} from 'react-router-dom';
88

99
class LoginPage extends Component {
@@ -29,16 +29,15 @@ class LoginPage extends Component {
2929
evt.preventDefault();
3030

3131
this.setState({loginError: null}, () => {
32-
axios.post('/login', {
33-
username: this.loginRef.current.value,
34-
password: this.passwordRef.current.value,
35-
rememberMe: this.rememberMeRef.current.checked
36-
})
37-
.then(resp => {
32+
AuthService.login(
33+
this.loginRef.current.value,
34+
this.passwordRef.current.value,
35+
this.rememberMeRef.current.checked,
36+
resp => {
3837
this.props.onLoginSuccess(resp);
3938
this.props.history.push('/dashboard');
40-
})
41-
.catch(err => this.setState({loginError: err.response.data.error}));
39+
},
40+
err => this.setState({loginError: err.error}));
4241
});
4342
};
4443

@@ -49,7 +48,6 @@ class LoginPage extends Component {
4948
};
5049

5150
render() {
52-
console.log(this.props.user);
5351
if (this.props.user) {
5452
return <Redirect to='/dashboard'/>;
5553
}
@@ -84,7 +82,6 @@ class LoginPage extends Component {
8482
</label>
8583
</div>
8684
<button className="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
87-
<p className="mt-5 mb-3 text-muted">&copy; 2017-2018</p>
8885
</form>
8986
</div>
9087
</div>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import axios from 'axios';
2+
3+
export default class {
4+
5+
static login(userName, password, shouldRemember, successCallback, failureCallback) {
6+
axios.post('/api/login', {
7+
username: userName,
8+
password: password,
9+
rememberMe: shouldRemember
10+
})
11+
.then(resp => successCallback(resp.data))
12+
.catch(err => failureCallback(err.response.data));
13+
}
14+
15+
static logout(callback) {
16+
axios.get('/api/logout').then(callback());
17+
}
18+
19+
static me(callback) {
20+
axios.get('/api/me').then(resp => callback(resp.data));
21+
}
22+
23+
}

src/main/java/pl/pateman/springbootreactbootstrapauthstarter/configuration/WebSecurityConfig.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
@EnableWebSecurity
2727
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
2828

29-
private static final String LOGIN_URL = "/login";
30-
private static final String LOGOUT_URL = "/logout";
29+
private static final String LOGIN_URL = "/api/login";
30+
private static final String LOGOUT_URL = "/api/logout";
3131
private static final String REMEMBER_ME_KEY = "uniqueAndSecret";
3232

3333
private final JSONLoginHandler loginHandler;
@@ -58,13 +58,16 @@ protected void configure(HttpSecurity http) throws Exception {
5858
.antMatchers(HttpMethod.GET, "/", "/*.json", "/static/**").permitAll()
5959
.antMatchers(HttpMethod.POST, LOGIN_URL).permitAll()
6060
.antMatchers(HttpMethod.POST, LOGOUT_URL).permitAll()
61+
.antMatchers("/api/me").permitAll()
6162
.antMatchers("/api/**").authenticated();
6263

6364
http.formLogin()
6465
.permitAll();
6566

6667
http.logout()
6768
.deleteCookies("JSESSIONID", "remember-me")
69+
.logoutUrl(LOGOUT_URL)
70+
.logoutSuccessUrl("/api/me")
6871
.permitAll();
6972

7073
http.addFilterAt(jsonAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package pl.pateman.springbootreactbootstrapauthstarter.controller;
2+
3+
import org.springframework.security.core.Authentication;
4+
import org.springframework.web.bind.annotation.GetMapping;
5+
import org.springframework.web.bind.annotation.RequestMapping;
6+
import org.springframework.web.bind.annotation.RestController;
7+
8+
@RestController
9+
@RequestMapping("/api/me")
10+
public class MeController {
11+
12+
@GetMapping
13+
public Authentication me(Authentication authentication) {
14+
return authentication;
15+
}
16+
17+
}

src/main/java/pl/pateman/springbootreactbootstrapauthstarter/security/JSONAuthenticationFilter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ
2929
InputStreamReader isr = new InputStreamReader(is);
3030
JsonReader jsonReader = new JsonReader(isr)) {
3131
JSONAuthenticationForm form = gson.fromJson(jsonReader, JSONAuthenticationForm.class);
32-
32+
if (form == null) {
33+
return null;
34+
}
3335
authRequest = new JSONAuthenticationToken(form.getUsername(), form.getPassword(), form.isRememberMe());
3436
} catch (IOException e) {
3537
authRequest = new JSONAuthenticationToken("", "", false);

0 commit comments

Comments
 (0)