Final Authentication and Authorization

Sekarang kita akan membuat hak akes seperti yg bisa hapus hanya admin, tidak bisa create movies sebelum login

Buat file baru di dalam folder Common dengan nama ProtectedRoute

ProtectedRoute.jsx

import React from "react";
import { Route, Redirect } from 'react-router-dom';
import auth from '../../services/AuthService';

const ProtectedRoute = ({ path, component: Component, render, ...rest }) => {
    return (
        <Route 
            {...rest}
            render={props => {
                if (!auth.getCurrentUser())
                    return(
                        <Redirect 
                            to={{ 
                                pathname: "/login",
                                state: { from: props.location }
                             }} />
                    ) 
                    return Component ? <Component {...props} /> : render(props);
            }} 
        />
    )
}

export default ProtectedRoute

App.js

import React, {Component} from 'react';
import { Route, Redirect, Switch } from 'react-router-dom';
import { ToastContainer } from 'react-toastify';

import Movies from './components/movies';
import MovieForm from './components/movieForm';
import Rentals from './components/Rentals';
import NotFound from './components/notFound';
import Customers from './components/Customers';
import NavBar from './components/NavBar';
import LoginFrom from './components/LoginForm';
import RegisterForm from './components/RegisterForm';
import Logout from './components/Logout';
import auth from './services/AuthService';
import ProtectedRoute from "./components/Common/ProtectedRoute";

import "react-toastify/dist/ReactToastify";
import './App.css';

class App extends Component {
  state = {};

  componentDidMount() {
    const user = auth.getCurrentUser();
    this.setState({ user });
  } 
  
  render() {
    const {user} = this.state;

    return (
      <>
      <ToastContainer />
        <NavBar user={this.state.user} />
        <main className="container">
          <Switch>
            <Route path="/register" component={RegisterForm} />
            <Route path="/login" component={LoginFrom} />
            <Route path="/logout" component={Logout} />
            <ProtectedRoute path="/movies/:id" component={MovieForm} />
            <Route path="/movies"
              render={props => <Movies { ...props } user={this.state.user} />}>
             </Route>
            <ProtectedRoute path="/customers" component={Customers}></ProtectedRoute>
            <Route path="/rentals" component={Rentals}></Route>
            <Route path="/not-found" component={NotFound}></Route>
            <Redirect from="/" exact to="/movies" />
            <Redirect to="not-found" />
          </Switch>
        </main>
      </>
    );
  }
}

export default App;

LoginForm.jsx

import React, { Component } from "react";
import {Redirect} from 'react-router-dom'
import Joi from "joi-browser";
import Form from "./Common/Form";
import auth from '../services/AuthService';

class LoginForm extends Form {
    state = {
        data : {
            username: '',
            password: ''
        },
        errors: {}
    };

    schema = {
        username: Joi.string().required().label("Username"),
        password: Joi.string().required().label("Password")
    };
    
    doSubmit = async () => {
        try {
            const { data } = this.state;
            await auth.login(data.username, data.password);
            
            const { state } = this.props.location;
            window.location = state ? state.from.pathname : "/";
        } catch (error) {
            if (error.response && error.response.status === 400) {
                const errors = { ...this.state.errors };
                errors.username = error.response.data;
                this.setState({ errors });
            }
        }
    };

    render(){
        if (auth.getCurrentUser()) return <Redirect to="/" />;

        return (
            <>
                <div>
                    <h1>Login</h1>
                    <form onSubmit={this.handleSubmit} >
                        {this.renderInput('username', 'Username')}
                        {this.renderInput('password', 'Password', "password")}
                        {this.renderButton('Login')}
                    </form>
                </div>
            </>
        )
    }
}

export default LoginForm

moviesTable.jsx

import React, { Component } from 'react';
import auth from '../services/AuthService';
import { Link } from 'react-router-dom';
import Table from './Common/Table';
import Like from './Common/Like';

// const x = <Like></Like>;


class MoviesTable extends Component {
    columns = [
        { path: 'title', 
          label: 'Title', 
          content: movie => <Link to={`/movies/${movie._id}`}>{movie.title}</Link> 
        },
        { path: 'genre.name', label: 'Genre' },
        { path: 'numberInStock', label: 'Stock' },
        { path: 'dailyRentalRate', label: 'Rate' },
        { key: "like",
          content: movie => <Like liked={movie.liked} onClick={() => this.props.onLike(movie)} />
        },
    ];

    deleteColumn = { 
      key: "delete",
      content: movie => (
        <button 
            onClick={() => this.props.onDelete(movie)}
            className="btn btn-danger btn-sm">
            Delete
        </button>
      )
        
    }

    constructor() {
      super();
      const user = auth.getCurrentUser();
      if(user && user.isAdmin){
        this.columns.push(this.deleteColumn)
      }
    }
    
    render(){
        const { movies, onSort, sortColumn } = this.props;

        return (
            <Table 
                columns={this.columns} 
                data={movies}
                sortColumn={sortColumn}
                onSort={onSort}
            />
        )
    }
}

export default MoviesTable

Tidak ada tombol delete ketika belom login atau login dengan akun selain admin

Login admin

Last updated

Was this helpful?