(राज्य प्रबंधन के लिए Redux का उपयोग करना)
यदि उपयोगकर्ता किसी भी यूआरएल को एक्सेस करने का प्रयास करता है, तो सबसे पहले मैं यह जांचने जा रहा हूं कि क्या उपलब्ध टोकन उपलब्ध है, यदि लॉगिन पृष्ठ पर रीडायरेक्ट नहीं किया जाता है, एक बार लॉगिन पेज का उपयोग करने के बाद उपयोगकर्ता लॉग इन करता है, तो हम इसे स्थानीय स्टोर के साथ-साथ हमारे redux राज्य में संग्रहीत करते हैं। (स्थानीय दुकान या कुकीज़..हम इस विषय को अभी के लिए संदर्भ से बाहर रखते हैं)।
अद्यतन और निजीकरण के रूप में redux राज्य के बाद से रेंडर किया जाएगा। अब हमारे पास टोकन एक्सेस है इसलिए हम होम पेज पर रीडायरेक्ट करने वाले हैं।
डिकोड किए गए प्राधिकरण पेलोड डेटा के साथ-साथ Redux राज्य में संग्रहीत करें और इसे संदर्भ प्रतिक्रिया के लिए पास करें। (हमें संदर्भ का उपयोग करने की आवश्यकता नहीं है, लेकिन हमारे किसी भी नेस्टेड बच्चे के घटकों में प्राधिकरण तक पहुँचने के लिए इसे संदर्भ से एक्सेस करने के बजाय प्रत्येक बच्चे के घटक को फिर से जोड़ने में आसान बनाता है) ।।
वे सभी मार्ग जिन्हें विशेष भूमिकाओं की आवश्यकता नहीं है, उन्हें लॉगिन के बाद सीधे एक्सेस किया जा सकता है .. यदि इसे व्यवस्थापक की तरह भूमिका की आवश्यकता है (हमने एक संरक्षित मार्ग बनाया है जो जाँचता है कि क्या उसकी वांछित भूमिका थी यदि अनधिकृत घटक को पुनर्निर्देशित नहीं किया गया है)
इसी तरह आपके किसी भी कंपोनेंट में अगर आपको बटन या किसी चीज़ को रोल के आधार पर डिसेबल करना है।
बस आप इस तरह से कर सकते हैं
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>
तो क्या होगा अगर यूजर लोकलस्टोरेज में डमी टोकन डालने की कोशिश करे। जैसा कि हमारे पास एक्सेस टोकन है, हम होम कंपोनेंट को रीडायरेक्ट करेंगे। मेरा होम कंपोनेंट डेटा हड़पने के लिए रेस्ट कॉल करेगा, क्योंकि jwt टोकन डमी था, बाकी कॉल अनधिकृत उपयोगकर्ता को वापस कर देगा। इसलिए मैं लॉगआउट कहता हूं (जो स्थानीयस्टोर को साफ कर देगा और फिर से लॉगिन पेज पर रीडायरेक्ट करेगा)। अगर होम पेज में स्टैटिक डेटा है और कोई एपीआई कॉल नहीं कर रहा है (तो आपको बैकएंड में टोकन-वेरिफाइड एप कॉल करना चाहिए ताकि आप चेक कर सकें कि होम पेज लोड करने से पहले टोकन असली है या नहीं)
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];
};
JODT टोकेन समोसे की सजावट
{
"authorization": {
"roles": [
"admin",
"operator"
]
},
"exp": 1591733170,
"user_id": 1,
"orig_iat": 1591646770,
"email": "hemanthvrm@stackoverflow",
"username": "hemanthvrm"
}