(Durum yönetimi için Redux kullanma)
Kullanıcı herhangi bir url'ye erişmeye çalışırsa, önce erişim belirtecinin mevcut olup olmadığını kontrol edeceğim, eğer oturum açma sayfasına yönlendirmiyorsa, Kullanıcı oturum açma sayfasını kullanarak oturum açtığında, bunu yerel depoda ve yeniden düzenleme durumumuzda saklarız. (yerel depolama veya tanımlama bilgileri..bu konuyu şimdilik bağlamın dışında tutuyoruz).
çünkü yeniden düzenleme durumu güncellendi ve özel yollar yeniden işlenecek. Artık erişim jetonumuz var, bu yüzden ana sayfaya yönlendireceğiz.
Kodu çözülen yetkilendirme yük verilerini yeniden düzenleme durumunda depolayın ve içeriğe tepki vermek için iletin. (Bağlam kullanmak zorunda değiliz, ancak iç içe geçmiş alt bileşenlerimizin herhangi birinde yetkilendirmeye erişmek, her bir alt bileşeni yeniden düzenlemeye bağlamak yerine bağlamdan erişimi kolaylaştırır) ..
Özel roller gerektirmeyen tüm rotalara giriş yapıldıktan sonra doğrudan erişilebilir. Yönetici gibi bir role ihtiyaç duyarsa (yetkisiz bileşene yönlendirmiyorsa, istenen role sahip olup olmadığını kontrol eden korumalı bir rota yaptık)
benzer şekilde, düğmeyi veya role bağlı bir şeyi devre dışı bırakmanız gerektiğinde bileşeninizden herhangi birinde.
basitçe bu şekilde yapabilirsin
const authorization = useContext(AuthContext);
const [hasAdminRole] = checkAuth({authorization, roleType:"admin"});
const [hasLeadRole] = checkAuth({authorization, roleType:"lead"});
<Button disable={!hasAdminRole} />Admin can access</Button>
<Button disable={!hasLeadRole || !hasAdminRole} />admin or lead can access</Button>
Öyleyse, kullanıcı yerel depoya sahte jeton eklemeye çalışırsa ne olur? Erişim belirtecimiz olduğu için, ev bileşenine yönlendireceğiz. Ev bileşenim verileri almak için dinlenme çağrısı yapacak, jwt token sahte olduğundan, dinlenme çağrısı yetkisiz kullanıcıyı döndürecektir. Bu yüzden oturumu kapatıyorum (bu, yerel depolamayı temizleyecek ve tekrar giriş sayfasına yönlendirecektir). Ana sayfada statik veriler varsa ve herhangi bir API çağrısı yapmıyorsa (o zaman, ana sayfayı yüklemeden önce jetonun GERÇEK olup olmadığını kontrol edebilmeniz için arka uçta token-doğrulama api çağrısına sahip olmanız gerekir)
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Switch } from 'react-router-dom';
import history from './utils/history';
import Store from './statemanagement/store/configureStore';
import Privateroutes from './Privateroutes';
import Logout from './components/auth/Logout';
ReactDOM.render(
<Store>
<Router history={history}>
<Switch>
<Route path="/logout" exact component={Logout} />
<Route path="/" exact component={Privateroutes} />
<Route path="/:someParam" component={Privateroutes} />
</Switch>
</Router>
</Store>,
document.querySelector('#root')
);
History.js
import { createBrowserHistory as history } from 'history';
export default history({});
Privateroutes.js
import React, { Fragment, useContext } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { AuthContext, checkAuth } from './checkAuth';
import App from './components/App';
import Home from './components/home';
import Admin from './components/admin';
import Login from './components/auth/Login';
import Unauthorized from './components/Unauthorized ';
import Notfound from './components/404';
const ProtectedRoute = ({ component: Component, roleType, ...rest })=> {
const authorization = useContext(AuthContext);
const [hasRequiredRole] = checkAuth({authorization, roleType});
return (
<Route
{...rest}
render={props => hasRequiredRole ?
<Component {...props} /> :
<Unauthorized {...props} /> }
/>)};
const Privateroutes = props => {
const { accessToken, authorization } = props.authData;
if (accessToken) {
return (
<Fragment>
<AuthContext.Provider value={authorization}>
<App>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" render={() => <Redirect to="/" />} />
<Route exact path="/home" component={Home} />
<ProtectedRoute
exact
path="/admin"
component={Admin}
roleType="admin"
/>
<Route path="/404" component={Notfound} />
<Route path="*" render={() => <Redirect to="/404" />} />
</Switch>
</App>
</AuthContext.Provider>
</Fragment>
);
} else {
return (
<Fragment>
<Route exact path="/login" component={Login} />
<Route exact path="*" render={() => <Redirect to="/login" />} />
</Fragment>
);
}
};
// my user reducer sample
// const accessToken = localStorage.getItem('token')
// ? JSON.parse(localStorage.getItem('token')).accessToken
// : false;
// const initialState = {
// accessToken: accessToken ? accessToken : null,
// authorization: accessToken
// ? jwtDecode(JSON.parse(localStorage.getItem('token')).accessToken)
// .authorization
// : null
// };
// export default function(state = initialState, action) {
// switch (action.type) {
// case actionTypes.FETCH_LOGIN_SUCCESS:
// let token = {
// accessToken: action.payload.token
// };
// localStorage.setItem('token', JSON.stringify(token))
// return {
// ...state,
// accessToken: action.payload.token,
// authorization: jwtDecode(action.payload.token).authorization
// };
// default:
// return state;
// }
// }
const mapStateToProps = state => {
const { authData } = state.user;
return {
authData: authData
};
};
export default connect(mapStateToProps)(Privateroutes);
checkAuth.js
import React from 'react';
export const AuthContext = React.createContext();
export const checkAuth = ({ authorization, roleType }) => {
let hasRequiredRole = false;
if (authorization.roles ) {
let roles = authorization.roles.map(item =>
item.toLowerCase()
);
hasRequiredRole = roles.includes(roleType);
}
return [hasRequiredRole];
};
ÇÖZÜLMÜŞ JWT TOKEN NUMUNESİ
{
"authorization": {
"roles": [
"admin",
"operator"
]
},
"exp": 1591733170,
"user_id": 1,
"orig_iat": 1591646770,
"email": "hemanthvrm@stackoverflow",
"username": "hemanthvrm"
}