One place for hosting & domains
      • Fast, Secure, Realiable

        Powerful shared hosting on enterprise hardware.


        • Easy control panel
        • 1-Click script install
        • SSD disk storage
        • Unlimited transfer
        • 24/7 technical support
        • 99% uptime guarantee
      • Unlimited Web Hosting

        All the Feature You Need
        In One Package

        Power and Stability Guaranteed

        Learn more  

        UNLIMITED WEB HOSTING

        63%

        OFF

        starting at

        $29/month

      • High performance SSD Server

        At vero eos et accusamus iusto odio dignissimos ducimus blanditiis.

        Sign Up Now!
      • GET THE DOMAIN
        YOU WANT


        FOR THE PRICE
        YOU LOVE

      Cara Menambah Autentikasi pada Aplikasi Anda dengan Flask-Login


      Pengantar

      Mengizinkan pengguna untuk log masuk ke aplikasi Anda adalah salah satu fitur paling umum yang akan ditambahkan ke aplikasi web Anda. Artikel ini akan membahas cara menambah autentikasi ke aplikasi Flask Anda dengan paket Flask-Login.

      Gif animasi dari aplikasi Flask dan kotak log masuk

      Kita akan membangun beberapa laman pendaftaran dan log masuk yang memungkinkan pengguna untuk log masuk dan mengakses laman-laman yang terlindungi, sedangkan pengguna yang tidak log masuk tidak dapat melihatnya. Kita akan mengambil informasi dari model pengguna dan menampilkannya di laman terlindungi kita ketika pengguna log masuk untuk menyimulasikan tampilan profil.

      Kita akan membahas yang berikut dalam artikel ini:

      • Menggunakan pustaka Flask-Login untuk manajemen sesi
      • Menggunakan utilitas Flash bawaan untuk melakukan hash kata sandi
      • Menambah laman terlindungi di aplikasi kita hanya untuk pengguna yang log masuk
      • Menggunakan Flask-SQLAlchemy untuk menciptakan model pengguna
      • Menciptakan formulir pendaftaran dan log masuk bagi pengguna kita untuk menciptakan akun dan log masuk
      • Memberikan pesan kesalahan flash ke pengguna ketika ada yang salah
      • Menggunakan informasi dari akun pengguna untuk menampilkan laman profil

      Kode sumber untuk proyek ini tersedia di GitHub.

      Prasyarat

      Untuk mengikuti tutorial ini, Anda membutuhkan hal berikut ini:

      Aplikasi kita akan menggunakan setelan pabrik aplikasi Flask dengan cetak biru. Kita akan memiliki satu cetak biru yang menangani segala sesuatu yang terkait dengan auth, dan kita akan memiliki cetak biru lainnya untuk rute reguler kita, yang termasuk indeks dan laman profil terlindungi. Dalam aplikasi sungguhan, Anda dapat mengurai fungsionalitas dengan cara apa pun yang Anda suka, tetapi solusi yang dibahas di sini akan bekerja dengan baik untuk tutorial ini.

      Berikut adalah diagram untuk memberikan gambaran tentang struktur berkas proyek Anda akan terlihat seperti apa setelah Anda menyelesaikan tutorial:

      .
      └── flask_auth_app
          └── project
              ├── __init__.py       # setup our app
              ├── auth.py           # the auth routes for our app
              ├── db.sqlite         # our database
              ├── main.py           # the non-auth routes for our app
              ├── models.py         # our user model
              └── templates
                  ├── base.html     # contains common layout and links
                  ├── index.html    # show the home page
                  ├── login.html    # show the login form
                  ├── profile.html  # show the profile page
                  └── signup.html   # show the signup form
      

      Seiring kita menjalani tutorial ini, kita akan menciptakan direktori dan berkas ini.

      Langkah 1 — Menginstal Paket

      Ada tiga paket utama yang diperlukan untuk proyek kita:

      • Flask
      • Flask-Login: untuk menangani sesi pengguna setelah autentikasi
      • Flask-SQLAlchemy: untuk mewakili antarmuka dan model pengguna dengan basis data kita

      Kita akan menggunakan SQLite untuk menghindari keharusan menginstal dependensi tambahan bagi basis data.

      Pertama-tama, kita akan mulai dengan menciptakan direktori proyek:

      Selanjutnya, kita perlu bernavigasi ke direktori proyek:

      Anda akan ingin menciptakan lingkungan Python jika Anda tidak memilikinya. Tergantung bagaimana Python terinstal pada mesin Anda, perintah Anda akan terlihat mirip seperti ini:

      • python3 -m venv auth
      • source auth/bin/activate

      Catatan: Anda dapat melihat tutorial yang relevan dengan lingkungan lokal untuk menyiapkan venv.

      Jalankan perintah berikut dari lingkungan virtual Anda untuk menginstal paket yang diperlukan:

      • pip install flask flask-sqlalchemy flask-login

      Karena kini Anda telah menginstal paket, Anda siap untuk menciptakan berkas aplikasi utama.

      Langkah 2 — Menciptakan Berkas Aplikasi Utama

      Mari kita mulai dengan menciptakan direktori project:

      Berkas pertama yang akan kita kerjakan adalah berkas __init__.py untuk proyek kita:

      Berkas ini akan memiliki fungsi untuk menciptakan aplikasi kita, yang akan menginisialisasi basis data dan mendaftarkan cetak biru kita. Saat ini, berkas ini tidak terlalu berguna, tetapi akan diperlukan selanjutnya untuk aplikasi kita. Kita perlu menginisialisasi SQLAlchemy, menetapkan beberapa nilai konfigurasi, dan mendaftarkan cetak biru kita di sini.

      project/__init__.py

      from flask import Flask
      from flask_sqlalchemy import SQLAlchemy
      
      # init SQLAlchemy so we can use it later in our models
      db = SQLAlchemy()
      
      def create_app():
          app = Flask(__name__)
      
          app.config['SECRET_KEY'] = 'secret-key-goes-here'
          app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
      
          db.init_app(app)
      
          # blueprint for auth routes in our app
          from .auth import auth as auth_blueprint
          app.register_blueprint(auth_blueprint)
      
          # blueprint for non-auth parts of app
          from .main import main as main_blueprint
          app.register_blueprint(main_blueprint)
      
          return app
      

      Setelah memiliki berkas aplikasi utama, kita dapat mulai menambahkan ke dalam rute kita.

      Langkah 3 — Menambahkan Rute

      Untuk rute, kita akan menggunakan dua cetak biru. Untuk cetak biru utama, kita akan memiliki laman beranda (/) dan laman profil (/profile) untuk setelah kita log masuk. Jika pengguna mencoba mengakses laman profil tanpa log masuk, mereka akan dikirim ke rute log masuk.

      Untuk cetak biru auth, kita akan memiliki rute untuk mengambil baik laman log masuk (/login) dan laman pendaftaran (/sign-up). Kita juga akan memiliki rute untuk menangani permintaan POST dari kedua rute itu. Terakhir, kita akan memiliki rute log keluar (/logout) untuk mengeluarkan pengguna aktif.

      Untuk sementara ini, kita akan mendefinisikan login, signup, dan logout dengan respons sederhana. Kita akan meninjaunya kembali pada langkah selanjutnya dan memperbaruinya dengan fungsionalitas yang diinginkan.

      Pertama-tama, ciptakan main.py untuk main_blueprint:

      project/main.py

      from flask import Blueprint
      from . import db
      
      main = Blueprint('main', __name__)
      
      @main.route('/')
      def index():
          return 'Index'
      
      @main.route('/profile')
      def profile():
          return 'Profile'
      

      Selanjutnya, ciptakan auth.py untuk auth_blueprint:

      project/auth.py

      from flask import Blueprint
      from . import db
      
      auth = Blueprint('auth', __name__)
      
      @auth.route('/login')
      def login():
          return 'Login'
      
      @auth.route('/signup')
      def signup():
          return 'Signup'
      
      @auth.route('/logout')
      def logout():
          return 'Logout'
      

      Di dalam terminal, Anda dapat menetapkan nilai FLASK_APP dan FLASK_DEBUG:

      • export FLASK_APP=project
      • export FLASK_DEBUG=1

      Variabel lingkungan FLASK_APP memberi instruksi pada Flask terkait cara memuat aplikasi. Ini harus mengarah ke tempat create_app berada. Untuk keperluan kita, kita akan mengarahkan ke direktori project.

      Variabel lingkungan FLASK_DEBUG diaktifkan dengan menetapkan nilainya menjadi 1. Ini akan mengaktifkan pengawakutu yang akan menampilkan kesalahan aplikasi di peramban.

      Pastikan Anda berada di direktori flask_auth_app, lalu jalankan proyeknya:

      Sekarang, dalam peramban web, Anda seharusnya dapat bernavigasi ke lima URL yang memungkinkan dan melihat teks yang dihasilkan yang didefinisikan dalam auth.py dan main.py.

      Misalnya, mengunjungi localhost:5000/profile akan menampilkan: Profile:

      Tangkapan layar dari proyek di localhost porta 5000 dalam peramban

      Kini setelah kita memverifikasi bahwa rute berperilaku seperti yang diharapkan, kita dapat melanjutkan ke penciptaan templat.

      Langkah 4 — Menciptakan Templat

      Mari kita lanjutkan dan menciptakan templat yang digunakan dalam aplikasi. Ini adalah langkah pertama sebelum kita dapat menerapkan fungsionalitas log masuk yang sebenarnya. Aplikasi kita akan menggunakan empat templat:

      • index.html
      • profile.html
      • login.html
      • signup.html

      Kita juga akan memiliki templat dasar yang akan memiliki kode umum untuk setiap lamannya. Dalam hal ini, templat dasar akan memiliki tautan navigasi dan tata letak umum dari laman. Mari kita ciptakan sekarang.

      Pertama-tama, ciptakan direktori template di bawah direktori project:

      • mkdir -p project/templates

      Kemudian, ciptakan base.html:

      • nano project/templates/base.html

      Selanjutnya, tambahkan kode berikut ke berkas base.html:

      project/templates/base.html

      <!DOCTYPE html>
      <html>
      
      <head>
          <meta charset="utf-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>Flask Auth Example</title>
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css" />
      </head>
      
      <body>
          <section class="hero is-primary is-fullheight">
      
              <div class="hero-head">
                  <nav class="navbar">
                      <div class="container">
      
                          <div id="navbarMenuHeroA" class="navbar-menu">
                              <div class="navbar-end">
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("main.index') }}" class="navbar-item">
                                      Home
                                  </a>
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("main.profile') }}" class="navbar-item">
                                      Profile
                                  </a>
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.login') }}" class="navbar-item">
                                      Login
                                  </a>
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.signup') }}" class="navbar-item">
                                      Sign Up
                                  </a>
                                  <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.logout') }}" class="navbar-item">
                                      Logout
                                  </a>
                              </div>
                          </div>
                      </div>
                  </nav>
              </div>
      
              <div class="hero-body">
                  <div class="container has-text-centered">
                     {% block content %}
                     {% endblock %}
                  </div>
              </div>
          </section>
      </body>
      
      </html>
      

      Kode ini akan menciptakan serangkaian menu yang terhubung ke setiap laman dari aplikasi dan daerah tempat konten akan muncul.

      Catatan: Di balik layar, kita menggunakan Bulma untuk menangani pengaturan gaya dan tata letak. Untuk pengetahuan yang lebih dalam tentang Bulma, pertimbangkan untuk membaca dokumentasi Bulma resmi.

      Selanjutnya, ciptakan templates/index.html:

      • nano project/templates/index.html

      Tambahkan kode berikut ke berkas yang baru saja diciptakan untuk menambahkan konten ke laman:

      project/templates/index.html

      {% extends "base.html" %}
      
      {% block content %}
      <h1 class="title">
        Flask Login Example
      </h1>
      <h2 class="subtitle">
        Easy authentication and authorization in Flask.
      </h2>
      {% endblock %}
      

      Kode ini akan menciptakan laman indeks dasar dengan judul dan subjudul.

      Selanjutnya, ciptakan templates/login.html:

      • nano project/templates/login.html

      Kode ini menghasilkan laman log masuk dengan bidang untuk Surel dan Kata Sandi. Ada juga kotak centang untuk “mengingat” suatu sesi log masuk.

      project/templates/login.html

      {% extends "base.html" %}
      
      {% block content %}
      <div class="column is-4 is-offset-4">
          <h3 class="title">Login</h3>
          <div class="box">
              <form method="POST" action="/login">
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="email" name="email" placeholder="Your Email" autofocus="">
                      </div>
                  </div>
      
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="password" name="password" placeholder="Your Password">
                      </div>
                  </div>
                  <div class="field">
                      <label class="checkbox">
                          <input type="checkbox">
                          Remember me
                      </label>
                  </div>
                  <button class="button is-block is-info is-large is-fullwidth">Login</button>
              </form>
          </div>
      </div>
      {% endblock %}
      

      Selanjutnya, ciptakan templates/signup.html:

      • nano project/templates/signup.html

      Tambahkan kode berikut untuk menciptakan laman pendaftaran dengan bidang untuk surel, nama, dan kata sandi:

      project/templates/signup.html

      {% extends "base.html" %}
      
      {% block content %}
      <div class="column is-4 is-offset-4">
          <h3 class="title">Sign Up</h3>
          <div class="box">
              <form method="POST" action="/signup">
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="email" name="email" placeholder="Email" autofocus="">
                      </div>
                  </div>
      
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="text" name="name" placeholder="Name" autofocus="">
                      </div>
                  </div>
      
                  <div class="field">
                      <div class="control">
                          <input class="input is-large" type="password" name="password" placeholder="Password">
                      </div>
                  </div>
      
                  <button class="button is-block is-info is-large is-fullwidth">Sign Up</button>
              </form>
          </div>
      </div>
      {% endblock %}
      

      Selanjutnya, ciptakan templates/profile.html:

      • nano project/templates/profile.html

      Tambahkan kode ini untuk menciptakan laman sederhana dengan judul yang dikodekan secara permanen untuk menyambut Anthony:

      project/templates/profile.html

      {% extends "base.html" %}
      
      {% block content %}
      <h1 class="title">
        Welcome, Anthony!
      </h1>
      {% endblock %}
      

      Nanti, kita akan menambahkan kode untuk menyapa pengguna siapa pun secara dinamis.

      Setelah Anda menambah templat, kita dapat memperbarui pernyataan respons di setiap rute ketika kita harus memberikan templat alih-alih teks.

      Selanjutnya, perbarui main.py dengan memodifikasi baris impor dan rute untuk index dan profile:

      project/main.py

      from flask import Blueprint, render_template
      ...
      @main.route('/')
      def index():
          return render_template('index.html')
      
      @main.route('/profile')
      def profile():
          return render_template('profile.html')
      

      Sekarang Anda akan memperbarui auth.py dengan memodifikasi baris impor dan rute untuk login dan signup:

      project/auth.py

      from flask import Blueprint, render_template
      ...
      @auth.route('/login')
      def login():
          return render_template('login.html')
      
      @auth.route('/signup')
      def signup():
          return render_template('signup.html')
      

      Setelah Anda membuat perubahan ini, laman pendaftaran akan terlihat seperti ini jika Anda bernavigasi ke /sign-up:

      Laman pendaftaran di /signup

      Anda seharusnya dapat melihat laman untuk /, /login, dan /profile juga.

      Kita akan membiarkan /logout untuk saat ini karena /logout tidak akan menampilkan templat saat selesai.

      Langkah 5 — Menciptakan Model Pengguna

      Model pengguna kita mewakili seberapa berartinya memiliki pengguna bagi aplikasi kita. Kita akan memiliki bidang untuk alamat surel, kata sandi, dan nama. Di aplikasi, Anda mungkin memutuskan bahwa Anda menginginkan lebih banyak informasi untuk disimpan per pengguna. Anda dapat menambah hal-hal seperti ulang tahun, foto profil, lokasi, atau preferensi pengguna apa pun.

      Model yang diciptakan dalam Flask-SQLAlchemy diwakili oleh kelas-kelas yang kemudian diterjemahkan ke tabel-tabel di dalam basis data. Atribut dari kelas-kelas itu lalu berubah menjadi kolom-kolom untuk tabel tersebut.

      Mari kita lanjutkan dan ciptakan model pengguna itu:

      Kode ini menciptakan model pengguna dengan kolom untuk id, email, password, dan name:

      project/models.py

      from . import db
      
      class User(db.Model):
          id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
          email = db.Column(db.String(100), unique=True)
          password = db.Column(db.String(100))
          name = db.Column(db.String(1000))
      

      Karena kini Anda telah menciptakan model pengguna, Anda dapat melanjutkan ke mengonfigurasi basis data.

      Langkah 6 — Mengonfigurasi Basis Data

      Seperti yang tercantum di dalam Prasyarat, kita akan menggunakan basis data SQLite. Kita dapat menciptakan basis data SQLite sendiri, tetapi mari kita biarkan Flask-SQLAlchemy yang melakukannya untuk kita. Kita telah memiliki jalur basis data yang ditentukan dalam berkas __init__.py, sehingga kita hanya perlu memberi tahu Flask-SQLAlchemy untuk menciptakan basis data di Python REPL.

      Jika Anda menghentikan aplikasi dan membuka Python REPL, kita dapat menciptakan basis data menggunakan metode create_all pada objek db. Pastikan Anda masih berada di lingkungan virtual dan di dalam direktori >flask_auth_app.

      • from project import db, create_app
      • db.create_all(app=create_app()) # pass the create_app result so Flask-SQLAlchemy gets the configuration.

      Catatan: Jika menggunakan penafsir Python merupakan hal baru bagi Anda, Anda dapat melihat dokumentasi resmi.

      Sekarang Anda akan melihat berkas db.sqlite di dalam direktori proyek. Basis data ini akan memiliki tabel pengguna kita di dalamnya.

      Langkah 7 — Menyiapkan Fungsi Otorisasi

      Untuk fungsi pendaftaran, kita akan mengambil data yang diketik pengguna ke dalam formulir dan menambahkannya ke dalam basis data kita. Sebelum menambahkannya, kita perlu memastikan bahwa pengguna tidak ada di basis data. Jika pengguna tidak ada, kita perlu memastikan kita melakukan hash kata sandi sebelum menempatkannya ke dalam basis data karena kita tidak mau kata sandi kita disimpan dalam teks polos.

      Mari kita mulai dengan menambahkan fungsi kedua untuk menangani data formulir POST. Dalam fungsi ini, kita akan mengumpulkan data yang diwariskan dari pengguna terlebih dahulu.

      Ciptakan fungsi dan tambahkan pengalihan di bagian bawah. Perintah ini akan memberikan pengalaman pengguna dari pendaftaran yang berhasil dan diarahkan ke Laman Log Masuk.

      Perbarui auth.py dengan memodifikasi baris impor dan menerapkan signup_post:

      project/auth.py

      from flask import Blueprint, render_template, redirect, url_for
      ...
      @auth.route('/signup', methods=['POST'])
      def signup_post():
          # code to validate and add user to database goes here
          return redirect(url_for('auth.login'))
      

      Sekarang, mari kita tambahkan sisa kode yang diperlukan untuk mendaftarkan pengguna.

      Untuk memulai, kita harus menggunakan objek yang diminta untuk mendapatkan data formulir.

      Lanjutkan untuk memperbarui auth.py dengan menambahkan impor dan menerapkan signup_post:

      auth.py

      from flask import Blueprint, render_template, redirect, url_for, request
      from werkzeug.security import generate_password_hash, check_password_hash
      from .models import User
      from . import db
      ...
      @auth.route('/signup', methods=['POST'])
      def signup_post():
          email = request.form.get('email')
          name = request.form.get('name')
          password = request.form.get('password')
      
          user = User.query.filter_by(email=email).first() # if this returns a user, then the email already exists in database
      
          if user: # if a user is found, we want to redirect back to signup page so user can try again
              return redirect(url_for('auth.signup'))
      
          # create a new user with the form data. Hash the password so the plaintext version isn't saved.
          new_user = User(email=email, name=name, password=generate_password_hash(password, method='sha256'))
      
          # add the new user to the database
          db.session.add(new_user)
          db.session.commit()
      
          return redirect(url_for('auth.login'))
      

      Catatan: Menyimpan kata sandi dalam teks polos adalah praktik keamanan yang buruk. Anda umumnya akan ingin memanfaatkan algoritma hash yang kompleks dan suatu garam kata sandi agar kata sandi tetap aman.

      Langkah 8 — Menguji Metode Pendaftaran

      Karena kini kita telah menyelesaikan metode pendaftaran, kita seharusnya dapat menciptakan pengguna baru. Gunakan formulir untuk menciptakan pengguna.

      Ada dua cara untuk memverifikasi jika pendaftaran berhasil: Anda dapat menggunakan penampil basis data untuk melihat baris yang ditambahkan ke tabel, atau Anda dapat mencoba mendaftar dengan alamat surel yang sama lagi, dan jika Anda mendapat pesan kesalahan, Anda tahu bahwa surel pertama telah disimpan dengan benar. Mari kita coba pendekatan itu.

      Kita dapat menambahkan kode untuk menginformasikan pengguna bahwa surel sudah ada dan memberi tahu mereka untuk pergi ke laman log masuk. Dengan memanggil fungsi flash, kita akan mengirim pesan ke permintaan selanjutnya, yang dalam hal ini adalah pengalihan. Laman yang kita kunjungi akan memiliki akses ke pesan itu di dalam templat.

      Pertama-tama, kita tambahkan flash sebelum kita mengalihkan kembali ke laman pendaftaran.

      project/auth.py

      from flask import Blueprint, render_template, redirect, url_for, request, flash
      ...
      @auth.route('/signup', methods=['POST'])
      def signup_post():
          ...
          if user: # if a user is found, we want to redirect back to signup page so user can try again
              flash('Email address already exists')
              return redirect(url_for('auth.signup'))
      

      Untuk mendapatkan pesan flash di dalam templat, kita dapat menambahkan kode ini di atas formulir. Ini akan menampilkan pesan secara langsung di atas formulir.

      project/templates/signup.html

      ...
      {% with messages = get_flashed_messages() %}
      {% if messages %}
          <div class="notification is-danger">
              {{ messages[0] }}. Go to <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.login') }}">login page</a>.
          </div>
      {% endif %}
      {% endwith %}
      <form method="POST" action="/signup">
      

      Kotak pendaftaran menampilkan pesan

      Langkah 9 — Menambahkan Metode Log Masuk

      Metode log masuk mirip dengan fungsi pendaftaran dalam hal kita akan mengambil informasi pengguna dan melakukan sesuatu dengannya. Dalam kasus ini, kita akan membandingkan alamat surel yang dimasukkan untuk melihat apakah alamat itu ada di dalam basis data. Jika demikian, kita akan menguji kata sandi yang disediakan pengguna dengan melakukan hash kata sandi yang diberikan pengguna dan membandingkannya dengan kata sandi yang telah melalui proses hash yang ada di dalam basis data. Kita tahu pengguna telah memasukkan kata sandi yang benar saat kedua kata sandi yang telah melalui proses hash sesuai.

      Setelah pengguna melewati pemeriksaan kata sandi, kita tahu bahwa pengguna itu memiliki kredensial yang benar dan kita dapat membuat mereka log masuk menggunakan Flask-Login. Dengan memanggil login_user, Flask-Login akan menciptakan sesi untuk pengguna tersebut yang akan tetap aktif selama pengguna tetap log masuk, yang akan memungkinkan pengguna untuk melihat laman terlindungi.

      Kita dapat memulai dengan rute baru untuk menangani data POSTed. Kita akan mengalihkan ke laman profil saat pengguna berhasil log masuk:

      project/auth.py

      ...
      @auth.route('/login', methods=['POST'])
      def login_post():
          # login code goes here
          return redirect(url_for('main.profile'))
      

      Sekarang, kita perlu memverifikasi apakah pengguna memiliki kredensial yang benar:

      project/auth.py

      ...
      @auth.route('/login', methods=['POST'])
      def login_post():
          email = request.form.get('email')
          password = request.form.get('password')
          remember = True if request.form.get('remember') else False
      
          user = User.query.filter_by(email=email).first()
      
          # check if the user actually exists
          # take the user-supplied password, hash it, and compare it to the hashed password in the database
          if not user or not check_password_hash(user.password, password):
              flash('Please check your login details and try again.')
              return redirect(url_for('auth.login')) # if the user doesn't exist or password is wrong, reload the page
      
          # if the above check passes, then we know the user has the right credentials
          return redirect(url_for('main.profile'))
      

      Mari kita tambahkan blok ke dalam templat sehingga pengguna dapat melihat pesan flash. Seperti formulir pendaftaran, mari kita tambahkan pesan kesalahan potensial secara langsung di atas formulir:

      project/templates/login.html

      ...
      {% with messages = get_flashed_messages() %}
      {% if messages %}
          <div class="notification is-danger">
              {{ messages[0] }}
          </div>
      {% endif %}
      {% endwith %}
      <form method="POST" action="/login">
      

      Kini kita telah memiliki kemampuan untuk mengatakan pengguna telah berhasil log masuk, tetapi pengguna tidak masuk ke mana pun. Ini adalah saat kita menggunakan Flask-Login untuk mengelola sesi pengguna.

      Sebelum kita memulai, kita memerlukan beberapa hal agar Flask-Login bekerja. Mulai dengan menambahkan UserMixin ke model Pengguna Anda. UserMixin akan menambahkan atribut Flask-Login ke model sehingga Flask-Login akan dapat bekerja dengannya.

      models.py

      from flask_login import UserMixin
      from . import db
      
      class User(UserMixin, db.Model):
          id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
          email = db.Column(db.String(100), unique=True)
          password = db.Column(db.String(100))
          name = db.Column(db.String(1000))
      

      Kemudian, kita perlu menentukan pemuat pengguna kita. Pemuat pengguna memberi tahu Flask-Login cara menemukan pengguna tertentu dari ID yang disimpan di dalam kuki sesi mereka. Kita dapat menambahkan ini ke dalam fungsi create_app bersama dengan kode init untuk Flask-Login:

      project/__init__.py

      ...
      from flask_login import LoginManager
      ...
      def create_app():
          ...
          db.init_app(app)
      
          login_manager = LoginManager()
          login_manager.login_view = 'auth.login'
          login_manager.init_app(app)
      
          from .models import User
      
          @login_manager.user_loader
          def load_user(user_id):
              # since the user_id is just the primary key of our user table, use it in the query for the user
              return User.query.get(int(user_id))
      

      Terakhir, kita dapat menambahkan fungsi login_user sebelum kita mengalihkan ke laman profil untuk menciptakan sesi:

      project/auth.py

      from flask_login import login_user
      from .models import User
      ...
      @auth.route('/login', methods=['POST'])
      def login_post():
          ...
          # if the above check passes, then we know the user has the right credentials
          login_user(user, remember=remember)
          return redirect(url_for('main.profile'))
      

      Dengan penyiapan Flask-Login, kita dapat menggunakan rute /login. Ketika semuanya disiapkan dengan benar, Anda akan melihat laman profil.

      Laman profil dengan

      Langkah 10 — Melindungi Laman

      Jika nama Anda bukan Anthony, Anda akan melihat bahwa nama Anda salah. Kita ingin profil menampilkan nama yang ada di dalam basis data. Pertama-tama, kita perlu melindungi laman itu, kemudian mengakses data pengguna untuk mendapatkan namanya.

      Untuk melindungi laman saat menggunakan Flask-Login, kita menambahkan dekorator @login_required antara rute dan fungsi. Ini akan mencegah pengguna yang tidak log masuk untuk melihat rute. Jika pengguna tidak log masuk, pengguna akan dialihkan ke laman log masuk, sesuai konfigurasi Flask-Login.

      Dengan rute yang dilengkapi oleh dekorator @login_required, kita akan memiliki kemampuan untuk menggunakan objek current_user di dalam fungsi. current_user ini mewakili pengguna dari basis data, dan kita dapat mengakses semua atribut pengguna itu dengan notasi titik. Misalnya, current_user.email, current_user.password, dan current_user.name, serta current_user.id akan memberikan nilai sebenarnya yang disimpan di dalam basis data bagi pengguna yang log masuk.

      Mari kita gunakan nama pengguna saat ini dan mengirimkannya ke templat. Kemudian, kita akan menggunakan nama itu dan menampilkan nilainya.

      project/main.py

      from flask_login import login_required, current_user
      ...
      @main.route('/profile')
      @login_required
      def profile():
          return render_template('profile.html', name=current_user.name)
      

      Lalu, dalam berkas profile.html, perbarui laman untuk menampilkan nilai name:

      project/templates/profile.html

      ...
      <h1 class="title">
        Welcome, {{ name }}!
      </h1>
      

      Setelah kita mengunjungi laman profil, kita akan melihat bahwa nama pengguna muncul.

      Laman sambutan pengguna dengan nama pengguna yang sedang log masuk saat ini

      Hal terakhir yang dapat kita lakukan adalah memperbarui tampilan log keluar. Kita dapat memanggil fungsi logout_user dalam suatu rute untuk log keluar. Kita memiliki dekorator @login_required karena tidak masuk akal untuk mengeluarkan pengguna yang sebelumnya tidak log masuk.

      project/auth.py

      from flask_login import login_user, logout_user, login_required
      ...
      @auth.route('/logout')
      @login_required
      def logout():
          logout_user()
          return redirect(url_for('main.index'))
      

      Setelah kita log keluar dan mencoba melihat laman profil lagi, kita melihat pesan kesalahan muncul. Ini karena Flask-Login melakukan flash pesan untuk kita ketika pengguna tidak diizinkan untuk mengakses laman.

      Laman log masuk dengan pesan menunjukkan bahwa pengguna harus log masuk untuk mengakses laman

      Satu hal terakhir yang dapat kita lakukan adalah memasukkan pernyataan if di dalam templat untuk menampilkan hanya tautan yang relevan dengan pengguna. Jadi, sebelum pengguna log masuk, mereka akan memiliki opsi untuk log masuk atau mendaftar. Setelah mereka log masuk, mereka dapat mengunjungi profil mereka atau log keluar:

      templates/base.html

      ...
      <div class="navbar-end">
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("main.index') }}" class="navbar-item">
              Home
          </a>
          {% if current_user.is_authenticated %}
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("main.profile') }}" class="navbar-item">
              Profile
          </a>
          {% endif %}
          {% if not current_user.is_authenticated %}
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.login') }}" class="navbar-item">
              Login
          </a>
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.signup') }}" class="navbar-item">
              Sign Up
          </a>
          {% endif %}
          {% if current_user.is_authenticated %}
          <a href="https://www.digitalocean.com/community/tutorials/{{ url_for("auth.logout') }}" class="navbar-item">
              Logout
          </a>
          {% endif %}
      </div>
      

      Laman beranda dengan navigasi Home, Login, dan Sign Up di bagian atas layar

      Dengan demikian, Anda telah berhasil membangun aplikasi Anda dengan autentikasi.

      Kesimpulan

      Kita telah menggunakan Flask-Login dan Flask-SQLAlchemy untuk membangun sistem log masuk pada aplikasi. Kita telah membahas cara melakukan autentikasi pengguna dengan menciptakan model pengguna dan menyimpan informasi pengguna terlebih dahulu. Kemudian, kita harus memverifikasi bahwa kata sandi pengguna adalah benar dengan melakukan hash kata sandi dari formulir dan membandingkannya dengan yang disimpan di basis data. Terakhir, kita menambahkan otorisasi ke aplikasi kita menggunakan dekorator @login_required di laman profil sehingga hanya pengguna yang sedang log masuk yang dapat melihat laman itu.

      Yang kita ciptakan dalam tutorial ini akan cukup untuk aplikasi yang kecil, tetapi jika Anda ingin memiliki fungsionalitas lebih banyak sejak awal, Anda mungkin dapat mempertimbangkan untuk menggunakan baik pustaka Flask-User atau Flask-Security, yang mana keduanya dibangun di atas pustaka Flask-Login.



      Source link

      Cara Membaca dan Mengatur Variabel Lingkungan dan Shell pada Linux


      Pengantar

      Ketika berinteraksi dengan server Anda melalui sesi shell, ada banyak potongan informasi yang dikumpulkan shell untuk menentukan perilaku dan aksesnya ke sumber daya. Sebagian dari pengaturan ini terkandung dalam pengaturan konfigurasi dan yang lainnya ditentukan oleh masukan pengguna.

      Salah satu cara agar shell melacak semua pengaturan dan detail ini adalah melalui suatu area yang dikelolanya, yang disebut lingkungan. Lingkungan adalah area yang dibangun shell setiap kali shell memulai sesi yang mengandung variabel yang mendefinisikan properti sistem.

      Dalam panduan ini, kita akan membahas cara berinteraksi dengan lingkungan dan membaca atau mengatur variabel lingkungan dan shell secara interaktif dan melalui berkas konfigurasi.

      Cara Variabel Lingkungan dan Lingkungan Bekerja

      Setiap kali sesi shell dimulai, suatu proses berlangsung untuk mengumpulkan dan mengompilasi semua informasi yang seharusnya tersedia bagi proses shell dan proses anaknya. Proses tersebut mendapatkan data untuk pengaturan ini dari berbagai berkas dan pengaturan berbeda pada sistem.

      Lingkungan menyediakan medium yang mana proses shell bisa mendapatkan atau mengatur pengaturan melaluinya, dan pada gilirannya memberikan ini ke proses anaknya.

      Lingkungan diimplementasikan sebagai string yang mewakili pasangan kunci-nilai. Jika banyak nilai diberikan, mereka biasanya akan dipisahkan dengan tanda karakter titik dua (:). Setiap pasang biasanya akan terlihat seperti ini:

      KEY=value1:value2:...
      

      Jika nilainya berisi spasi kosong yang signifikan, tanda kutip akan digunakan:

      KEY="value with spaces"
      

      Kunci dari skenario ini adalah variabel. Variabel ini berupa salah satu dari dua jenis, variabel lingkungan atau variabel shell.

      Variabel lingkungan adalah variabel yang didefinisikan untuk shell saat ini dan diwarisi oleh shell atau proses anak apa pun. Variabel lingkungan digunakan untuk memasukkan informasi ke dalam proses yang dihasilkan dari shell.

      Variabel shell adalah variabel yang terkandung secara eksklusif di dalam shell tempat variabel tersebut diatur atau didefinisikan. Variabel ini sering digunakan untuk melacak data yang hanya bertahan sebentar, seperti direktori kerja yang aktif saat ini.

      Berdasarkan konvensi, jenis variabel ini biasanya didefinisikan dengan menggunakan huruf kapital semua. Ini membantu pengguna untuk membedakan variabel lingkungan di dalam konteks lainnya.

      Mencetak Variabel Shell dan Lingkungan

      Setiap sesi shell terus melacak variabel shell dan lingkungannya sendiri. Kita dapat mengakses variabel ini dengan beberapa cara yang berbeda.

      Kita dapat melihat daftar semua variabel lingkungan kita dengan perintah env atau printenv. Dalam kondisi asalinya, perintah ini seharusnya berfungsi sama:

      Output

      SHELL=/bin/bash TERM=xterm USER=demouser LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:... MAIL=/var/mail/demouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/demouser LANG=en_US.UTF-8 SHLVL=1 HOME=/home/demouser LOGNAME=demouser LESSOPEN=| /usr/bin/lesspipe %s LESSCLOSE=/usr/bin/lesspipe %s %s _=/usr/bin/printenv

      Ini adalah tipikal keluaran dari printenv dan env. Perbedaan antara dua perintah ini hanya terlihat dalam fungsionalitasnya yang lebih spesifik. Misalnya, dengan printenv, Anda dapat meminta nilai dari masing-masing variabel:

      Output

      /bin/bash

      Di sisi lain, env memungkinkan Anda memodifikasi lingkungan tempat program berjalan dengan memberi suatu set definisi variabel ke perintah seperti ini:

      • env VAR1="value" command_to_run command_options

      Seperti kita pelajari di atas, karena proses anak biasanya mewarisi variabel lingkungan dari proses induk, ini memberi Anda kesempatan untuk menimpa nilai atau menambah variabel tambahan untuk anaknya.

      Seperti yang Anda lihat dari keluaran perintah printenv kita, ada beberapa variabel lingkungan yang disiapkan melalui berkas sistem dan proses tanpa masukan kita.

      Ini menunjukkan variabel lingkungan, tetapi bagaimana kita melihat variabel shell?

      Perintah set dapat digunakan untuk ini. Jika kita mengetik set tanpa parameter tambahan, kita akan mendapatkan daftar dari semua variabel shell, variabel lingkungan, variabel lokal, dan fungsi shell:

      Output

      BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() . . .

      Ini biasanya merupakan daftar yang besar. Anda mungkin ingin memasukkannya ke dalam program pager sehingga dapat lebih mudah menangani jumlah keluaran yang besar ini:

      Jumlah informasi tambahan yang kita terima agak berlebihan. Kita mungkin tidak perlu tahu semua fungsi bash yang didefinisikan, misalnya.

      Kita dapat membersihkan keluaran dengan menentukan bahwa set seharusnya beroperasi dalam mode POSIX, yang tidak akan mencetak fungsi shell. Kita dapat mengeksekusinya dalam subshell sehingga ini tidak mengubah lingkungan kita saat ini:

      Ini akan membuat daftar dari semua variabel lingkungan dan shell yang didefinisikan.

      Kita dapat mencoba untuk membandingkan keluaran ini dengan keluaran dari perintah env atau printenv untuk mencoba mendapatkan daftar dari variabel shell saja, tetapi ini akan menjadi tidak sempurna karena perintah-perintah ini memiliki cara yang berbeda untuk menampilkan keluaran informasi:

      • comm -23 <(set -o posix; set | sort) <(env | sort)

      Kemungkinan ini akan tetap menyertakan beberapa variabel lingkungan, mengingat nilai yang dikutip oleh keluaran perintah set, sementara perintah printenv dan env tidak mengutip nilai-nilai string.

      Ini seharusnya tetap memberi Anda ide yang bagus tentang variabel lingkungan dan shell yang diatur dalam sesi Anda.

      Variabel ini digunakan untuk segala macam hal. Mereka memberikan cara alternatif untuk mengatur nilai-nilai persisten pada sesi di antara berbagai proses, tanpa membuat perubahan terhadap berkas.

      Variabel Lingkungan dan Shell Umum

      Sebagian variabel lingkungan dan shell sangat berguna dan cukup sering direferensikan. Berikut adalah beberapa variabel lingkungan umum yang Anda akan jumpai:

      • SHELL: Ini mendeskripsikan shell yang akan menginterpretasikan perintah apa pun yang Anda ketik. Dalam kebanyakan kasus, ini adalah bash secara asali, tetapi nilai lain dapat ditetapkan jika Anda lebih memilih opsi lainnya.
      • TERM: Ini menentukan jenis terminal untuk menjalankan emulasi saat menjalankan shell. Terminal perangkat keras yang berbeda dapat diemulasi untuk kebutuhan pengoperasian yang berbeda. Anda biasanya tidak perlu khawatir tentang hal ini.
      • USER: Pengguna yang sedang log masuk saat ini.
      • PWD: Direktori kerja saat ini.
      • OLDPWD: Direktori kerja sebelumnya. Ini disimpan oleh shell agar Anda dapat beralih kembali ke direktori sebelumnya dengan menjalankan cd -.
      • LS_COLORS: Ini mendefinisikan kode warna yang digunakan untuk menambahkan keluaran berwarna secara opsional ke perintah ls. Ini digunakan untuk membedakan jenis berkas yang berbeda dan memberikan lebih banyak informasi kepada pengguna secara sekilas.
      • MAIL: Jalur ke kotak surat pengguna saat ini.
      • PATH: Daftar direktori yang diperiksa sistem saat mencari perintah. Ketika pengguna mengetik perintah, sistem akan memeriksa direktori dengan urutan seperti ini untuk mencari perintah yang dapat dieksekusi.
      • LANG: Pengaturan bahasa dan lokalisasi saat ini, termasuk pengodean karakter.
      • HOME: Direktori rumah pengguna saat ini.
      • _: Perintah terbaru yang dieksekusi sebelumnya.

      Selain variabel lingkungan ini, beberapa variabel shell yang Anda akan sering lihat adalah:

      • BASHOPTS: Daftar opsi yang digunakan saat bash dieksekusi. Ini dapat berguna untuk mencari tahu apakah lingkungan shell akan beroperasi dengan cara yang Anda inginkan.
      • BASH_VERSION: Versi bash yang sedang dieksekusi, dalam bentuk yang dapat dibaca manusia.
      • BASH_VERSINFO: Versi bash, dalam keluaran yang dapat dibaca mesin.
      • COLUMNS: Jumlah lebar kolom yang sedang digunakan untuk menampilkan keluaran di layar.
      • DIRSTACK: Tumpukan direktori yang tersedia dengan perintah pushd dan popd.
      • HISTFILESIZE: Histori jumlah baris dari perintah yang disimpan ke berkas.
      • HISTSIZE: Riwayat jumlah baris dari perintah yang diizinkan dalam memori.
      • HOSTNAME: Nama hos dari komputer saat ini.
      • IFS: Pemisah bidang internal untuk memisahkan masukan di baris perintah. Secara asali, ini adalah spasi.
      • PS1: Definisi prompt perintah primer. Ini digunakan untuk mendefinisikan tampilan prompt saat Anda memulai sesi shell. PS2 digunakan untuk menyatakan prompt sekunder saat perintah terdiri dari beberapa baris perintah.
      • SHELLOPTS: Opsi shell yang dapat diatur dengan opsi set.
      • UID: UID dari pengguna saat ini.

      Mengatur Variabel Shell dan Lingkungan

      Untuk lebih memahami perbedaan antara variabel shell dan lingkungan, serta untuk memperkenalkan sintaks untuk pengaturan variabel ini, kita akan melakukan demonstrasi kecil.

      Menciptakan Variabel Shell

      Kita akan mulai dengan mendefinisikan variabel shell di dalam sesi kita saat ini. Ini mudah untuk dilakukan; kita hanya perlu menentukan nama dan nilai. Kita akan mengikuti konvensi menggunakan huruf besar untuk nama variabel, dan mengaturnya ke string sederhana.

      Di sini, kita telah menggunakan kutipan karena nilai variabel kita mengandung spasi. Lebih jauh lagi, kita telah menggunakan tanda kutip tunggal karena tanda seru adalah karakter khusus di dalam shell bash yang biasanya mengembang ke riwayat bash jika tombol Esc tidak ditekan atau dimasukkan ke dalam kutipan tunggal.

      Sekarang kita memiliki variabel shell. Variabel ini tersedia di sesi kita saat ini, tetapi tidak akan diberikan ke proses anak.

      Kita dapat melihatnya dengan mencari variabel baru kita menggunakan grep di dalam keluaran set:

      Output

      TEST_VAR='Hello World!'

      Kita dapat memverifikasi bahwa ini bukan variabel lingkungan dengan mencoba hal yang sama menggunakan printenv:

      Seharusnya tidak ada keluaran yang dihasilkan.

      Mari kita anggap ini sebagai kesempatan untuk menunjukkan cara mengakses nilai dari variabel shell atau lingkungan apa pun.

      Output

      Hello World!

      Seperti yang Anda lihat, lakukan referensi nilai variabel dengan mengawalinya menggunakan tanda $. Shell menganggap ini berarti shell harus mengganti nilai variabel saat menjumpainya.

      Jadi kini kita memiliki variabel shell. Ini seharusnya tidak diberikan ke proses anak apa pun. Kita dapat menghasilkan shell bash yang baru dari dalam shell bash kita saat ini untuk menunjukkan:

      Jika kita mengetik bash untuk menghasilkan shell anak, lalu mencoba untuk mengakses konten dari variabel, tidak akan ada yang ditampilkan. Inilah yang kita harapkan.

      Kembalilah ke shell asli kita dengan mengetik exit:

      Menciptakan Variabel Lingkungan

      Sekarang, mari kita ubah variabel shell menjadi variabel lingkungan. Kita dapat melakukannya dengan mengekspor variabel. Perintah untuk melakukannya dinamakan:

      Ini akan mengubah variabel kita menjadi variabel lingkungan. Kita dapat memeriksanya dengan memeriksa daftar lingkungan kita lagi:

      Output

      TEST_VAR=Hello World!

      Kali ini, variabel kita muncul. Mari kita coba eksperimen kita dengan shell anak lagi:

      Output

      Hello World!

      Hebat! Shell anak kita telah menerima variabel yang diatur oleh induknya. Sebelum kita keluar dari shell anak ini, mari kita coba untuk mengekspor variabel lainnya. Kita dapat mengatur variabel lingkungan dalam satu langkah tunggal seperti ini:

      • export NEW_VAR="Testing export"

      Uji bahwa ini telah diekspor sebagai variabel lingkungan:

      Output

      NEW_VAR=Testing export

      Sekarang, mari kita keluar dan kembali ke shell asli kita:

      Mari kita lihat apakah variabel baru tersedia:

      Tidak ada yang ditampilkan.

      Ini karena variabel lingkungan hanya diberikan ke proses anak. Tidak ada cara bawaan untuk mengatur variabel lingkungan dari shell induk. Ini adalah hal bagus dalam kebanyakan kasus dan mencegah program dari memengaruhi lingkungan operasi dari tempat mereka dipanggil.

      Variabel NEW_VAR telah diatur sebagai variabel lingkungan di dalam shell anak kita. Variabel ini akan tersedia untuk dirinya sendiri dan shell serta proses anak dari variabel ini. Ketika kita keluar dan kembali ke shell utama, lingkungan itu telah dihancurkan.

      Melakukan Demosi dan Menghapus Pengaturan Variabel

      Kita masih memiliki variabel TEST_VAR yang didefinisikan sebagai variabel lingkungan. Kita dapat mengubahnya kembali ke variabel shell dengan mengetik:

      Ini bukan lagi variabel lingkungan:

      Namun, ini masih merupakan variabel shell:

      Output

      TEST_VAR='Hello World!'

      Jika kita ingin sepenuhnya menghapus pengaturan variabel, baik shell atau lingkungan, kita dapat melakukannya dengan perintah unset:

      Kita dapat memverifikasi bahwa ini tidak lagi diatur:

      Tidak ada yang dihasilkan karena variabel telah dihapus pengaturannya.

      Mengatur Variabel Lingkungan saat Log Masuk

      Kita telah menyebutkan bahwa banyak program menggunakan variabel lingkungan untuk memutuskan cara spesifik pengoperasian. Kita tidak ingin harus menyiapkan variabel penting setiap kali kita memulai sesi shell baru, dan kita telah melihat seberapa banyak variabel yang sudah diatur saat log masuk, jadi bagaimana cara membuat dan mendefinisikan variabel secara otomatis?

      Ini sebenarnya adalah masalah yang lebih rumit daripada kelihatannya, karena banyak berkas konfigurasi yang dibaca shell bash tergantung cara sesi dimulai.

      Perbedaan Sesi Shell Log Masuk, Non-Log Masuk, Interaktif, dan Non-Interaktif

      Shell bash membaca berkas konfigurasi yang berbeda tergantung pada cara sesi dimulai.

      Satu perbedaan antara berbagai sesi adalah apakah shell dihasilkan sebagai sesi log masuk atau non-log masuk.

      Shell log masuk adalah sesi shell yang dimulai dengan mengautentikasi pengguna. Jika Anda masuk ke sesi terminal atau melalui SSH dan mengautentikasi, sesi shell akan diatur sebagai shell log masuk.

      Jika Anda memulai sesi shell baru dari dalam sesi yang terautentikasi, seperti yang kita lakukan dengan memanggil perintah bash dari terminal, sesi shell non-log masuk akan dimulai. Anda tidak diminta detail autentikasi saat memulai shell anak.

      Perbedaan lainnya yang dapat dibuat adalah bahwa sesi shell adalah interaktif atau non-interaktif.

      Sesi shell interaktif adalah sesi shell yang melekat ke terminal. Sesi shell non-interaktif adalah sesi shell yang tidak melekat ke sesi terminal.

      Jadi, setiap sesi shell diklasifikasikan baik sebagai log masuk atau non-log masuk dan interaktif atau non-interaktif.

      Sesi normal yang dimulai dengan SSH biasanya merupakan shell log masuk interaktif. Skrip yang dijalankan dari baris perintah biasanya dijalankan dalam shell non-interaktif dan non-log masuk. Sesi terminal dapat berupa kombinasi dari dua properti ini.

      Apakah sesi shell yang diklasifikasikan sebagai shell log masuk atau non-log masuk memiliki implikasi pada berkas yang dibaca untuk menginisialisasi sesi shell.

      Sesi yang dimulai sebagai sesi log masuk akan membaca detail konfigurasi dari berkas /etc/profile terlebih dahulu. Kemudian akan mencari berkas konfigurasi shell log masuk pertama di dalam direktori rumah pengguna untuk mendapatkan detail konfigurasi spesifik pengguna.

      Sesi ini membaca berkas pertama yang dapat ditemukan dari ~/.bash_profile, ~/.bash_login, dan ~/.profile serta tidak membaca berkas lainnya lebih jauh.

      Sebaliknya, sesi yang didefinisikan sebagai shell non-log masuk akan membaca /etc/bash.bashrc dan kemudian berkas spesifik pengguna ~/.bashrc untuk membangun lingkungannya.

      Shell non-interaktif membaca variabel lingkungan bernama BASH_ENV dan membaca berkas yang ditentukan untuk mendefinisikan lingkungan baru.

      Mengimplementasikan Variabel Lingkungan

      Seperti yang Anda lihat, ada berbagai berkas berbeda yang biasanya kita perlu perhatikan untuk menyesuaikan pengaturan kita.

      Ini memberikan banyak fleksibilitas yang dapat membantu dalam situasi spesifik saat kita menginginkan pengaturan tertentu dalam shell log masuk, dan pengaturan lainnya dalam shell non-log masuk. Namun, kita kebanyakan menginginkan pengaturan yang sama dalam kedua situasi.

      Untungnya, kebanyakan distribusi Linux mengonfigurasi berkas konfigurasi log masuk untuk mengambil sumber dari berkas konfigurasi non-log masuk. Ini berarti bahwa Anda dapat mendefinisikan variabel lingkungan yang Anda inginkan dalam kedua situasi di berkas konfigurasi non-log masuk. Mereka kemudian akan dibaca dalam kedua skenario.

      Kita biasanya akan mengatur variabel lingkungan spesifik pengguna, dan kita biasanya ingin pengaturan tersedia di dalam shell log masuk serta non-log masuk. Ini berarti bahwa tempat untuk mendefinisikan variabel ini ada di dalam berkas ~/.bashrc.

      Buka berkas ini sekarang:

      Berkas ini kemungkinan besar sudah berisi sedikit data. Sebagian besar definisi di sini adalah untuk mengatur opsi bash, yang tidak berhubungan dengan variabel lingkungan. Anda dapat mengatur variabel lingkungan seperti yang Anda inginkan dari baris perintah:

      Variabel lingkungan baru apa pun dapat ditambahkan di mana saja di dalam berkas ~/.bashrc, selama mereka tidak ditempatkan di tengah perintah lainnya atau untuk loop. Kemudian, kita dapat menyimpan dan menutup berkas. Saat Anda memulai sesi shell berikutnya, pernyataan variabel lingkungan akan dibaca dan diberikan ke lingkungan shell. Anda dapat memaksa sesi saat ini untuk membaca berkas sekarang dengan mengetik:

      Jika Anda perlu mengatur variabel seluruh sistem, Anda mungkin ingin mempertimbangkan untuk menambahkan mereka ke /etc/profile, /etc/bash.bashrc, atau /etc/environment.

      Kesimpulan

      Variabel lingkungan dan shell selalu ada di dalam sesi shell dan dapat menjadi sangat berguna. Mereka adalah cara yang menarik bagi proses induk untuk mengatur detail konfigurasi bagi anak-anaknya, dan merupakan cara mengatur opsi di luar berkas.

      Ini memiliki banyak keuntungan dalam situasi tertentu. Misalnya, beberapa mekanisme penyebaran bergantung pada variabel lingkungan untuk mengonfigurasi informasi autentikasi. Ini berguna karena mekanismenya tidak perlu menyimpannya di dalam berkas yang mungkin dapat terlihat oleh pihak luar.

      Ada banyak skenario lain yang lebih biasa dan umum, saat Anda perlu membaca atau mengubah lingkungan sistem Anda. Alat dan teknik ini seharusnya memberi Anda fondasi yang baik untuk membuat perubahan ini dan menggunakannya dengan benar.



      Source link

      Cara Menambah Ruang Swap pada Ubuntu 20.04


      Pengantar

      Salah satu cara untuk menghindari kesalahan kehabisan memori dalam aplikasi adalah dengan menambahkan sejumlah ruang swap ke server Anda. Dalam panduan ini, kita akan membahas cara menambah suatu berkas swap ke server Ubuntu 20.04.

      Peringatan: Meskipun biasanya swap disarankan untuk sistem yang menggunakan hard drive berputar tradisional, harap diperhatikan bahwa melakukan swap pada SSD dapat menyebabkan masalah terkait degradasi perangkat keras seiring waktu. Karena itu, kami tidak menyarankan untuk mengaktifkan swap pada DigitalOcean atau penyedia lainnya yang menggunakan penyimpanan SSD.

      Apa itu Swap?

      Swap adalah bagian dari penyimpanan hard drive yang telah disisihkan pada sistem operasi untuk secara sementara menyimpan data yang tidak dapat lagi disimpan di RAM. Ini memungkinkan Anda untuk menambah jumlah informasi yang dapat disimpan oleh server Anda di dalam memori yang sedang bekerja, dengan beberapa peringatan. Ruang swap pada hard drive akan digunakan terutama saat tidak ada lagi ruang yang cukup di RAM untuk menyimpan data aplikasi yang sedang digunakan.

      Informasi yang ditulis ke diska akan lebih lambat secara signifikan dibandingkan informasi yang disimpan dalam RAM, tetapi sistem operasi akan lebih memilih untuk tetap menjalankan data aplikasi dalam memori dan menggunakan swap untuk data yang lebih tua. Secara garis besar, memiliki ruang swap sebagai pilihan alternatif saat RAM sistem Anda habis dapat menjadi jaring pengaman yang baik terhadap eksepsi kehabisan memori pada sistem dengan penyimpanan non-SSD.

      Langkah 1 – Memeriksa Sistem untuk Informasi Swap

      Sebelum memulai, kita dapat memeriksa apakah sistem sudah memiliki sebagian ruang swap yang tersedia. Dimungkinkan untuk memiliki beberapa berkas swap atau partisi swap, tetapi pada umumnya satu sudah cukup.

      Kita dapat melihat apakah sistem memiliki swap yang terkonfigurasi dengan mengetik:

      Jika Anda tidak mendapat keluaran apa pun, ini berarti sistem Anda tidak memiliki ruang swap yang tersedia saat ini.

      Anda dapat memverifikasi bahwa tidak ada swap yang aktif dengan menggunakan utilitas free:

      Output

      total used free shared buff/cache available Mem: 981Mi 122Mi 647Mi 0.0Ki 211Mi 714Mi Swap: 0B 0B 0B

      Seperti yang Anda lihat di baris Swap pada keluaran, tidak ada swap yang aktif pada sistem.

      Langkah 2 – Memeriksa Ruang Tersedia pada Partisi Hard Drive

      Sebelum menciptakan berkas swap, kita akan memeriksa penggunaan diska saat ini untuk memastikan kita memiliki cukup ruang. Lakukan ini dengan mengetik:

      Output

      Filesystem Size Used Avail Use% Mounted on udev 474M 0 474M 0% /dev tmpfs 99M 932K 98M 1% /run /dev/vda1 25G 1.4G 23G 7% / tmpfs 491M 0 491M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 491M 0 491M 0% /sys/fs/cgroup /dev/vda15 105M 3.9M 101M 4% /boot/efi /dev/loop0 55M 55M 0 100% /snap/core18/1705 /dev/loop1 69M 69M 0 100% /snap/lxd/14804 /dev/loop2 28M 28M 0 100% /snap/snapd/7264 tmpfs 99M 0 99M 0% /run/user/1000

      Perangkat dengan / di dalam kolom Mounted on adalah diska kita dalam kasus ini. Kita memiliki banyak ruang yang tersedia dalam contoh ini (hanya digunakan 1,4 G). Penggunaan Anda mungkin akan berbeda.

      Meskipun ada banyak pendapat tentang ukuran ruang swap yang sesuai, hal itu benar-benar bergantung pada preferensi pribadi dan persyaratan aplikasi Anda. Secara umum, jumlah yang sama atau dua kali dari jumlah RAM pada sistem Anda adalah titik awal yang baik. Patokan yang baik lainnya adalah swap apa pun di atas 4 G mungkin tidak diperlukan jika Anda hanya menggunakannya sebagai pilihan alternatif RAM.

      Langkah 3 – Menciptakan Berkas Swap

      Kini setelah kita mengetahui ruang hard drive yang tersedia, kita dapat menciptakan berkas swap di sistem kita. Kita akan mengalokasikan berkas dengan ukuran yang diinginkan yang bernama swapfile di direktori root (/) kita.

      Cara terbaik untuk menciptakan berkas swap adalah dengan program fallocate. Perintah ini seketika menciptakan berkas dengan ukuran yang ditentukan.

      Karena server dalam contoh kita memiliki 1 G RAM, kita akan menciptakan berkas 1 G dalam panduan ini. Sesuaikan ini untuk memenuhi kebutuhan server Anda:

      • sudo fallocate -l 1G /swapfile

      Kita dapat memverifikasi bahwa jumlah ruang yang benar telah disiapkan dengan mengetik:

      • -rw-r--r-- 1 root root 1.0G Apr 25 11:14 /swapfile

      Berkas telah dibuat dengan menyisihkan jumlah ruang yang benar.

      Langkah 4 – Mengaktifkan Berkas Swap

      Karena sudah memiliki berkas dengan ukuran yang benar, kita perlu mengubahnya menjadi ruang swap yang sesungguhnya.

      Pertama-tama, kita perlu untuk mengunci izin berkas sehingga hanya pengguna dengan privilese root yang dapat membaca konten. Ini mencegah pengguna normal untuk dapat mengakses berkas, yang akan memiliki implikasi keamanan yang signifikan.

      Buat berkas hanya dapat diakses oleh root dengan mengetik:

      Lakukan verifikasi perubahan izin dengan mengetik:

      Output

      -rw------- 1 root root 1.0G Apr 25 11:14 /swapfile

      Seperti yang terlihat, hanya pengguna root yang memiliki bendera baca dan tulis yang diaktifkan.

      Sekarang kita dapat menandai berkas sebagai ruang swap dengan mengetik:

      Output

      Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes) no label, UUID=6e965805-2ab9-450f-aed6-577e74089dbf

      Setelah menandai berkas, kita dapat mengaktifkan berkas swap, yang mengizinkan sistem kita untuk mulai menggunakannya:

      Lakukan verifikasi bahwa swap tersedia dengan mengetik:

      Output

      NAME TYPE SIZE USED PRIO /swapfile file 1024M 0B -2

      Kita dapat memeriksa keluaran utilitas free lagi untuk menguatkan temuan kita:

      Output

      total used free shared buff/cache available Mem: 981Mi 123Mi 644Mi 0.0Ki 213Mi 714Mi Swap: 1.0Gi 0B 1.0Gi

      Swap telah berhasil disiapkan dan sistem operasi kita akan mulai menggunakannya ketika diperlukan.

      Langkah 5 – Membuat Berkas Swap Jadi Permanen

      Perubahan terbaru kita telah mengaktifkan berkas swap untuk sesi ini. Namun, jika kita melakukan boot ulang, server tidak akan mempertahankan pengaturan swap secara otomatis. Kita dapat mengubah ini dengan menambahkan berkas swap ke berkas /etc/fstab.

      Cadangkan berkas /etc/fstab seandainya ada kesalahan:

      • sudo cp /etc/fstab /etc/fstab.bak

      Tambahkan informasi berkas swap di akhir berkas /etc/fstab dengan mengetik:

      • echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

      Selanjutnya, kita akan meninjau beberapa pengaturan yang dapat kita perbarui untuk menyetel ruang swap.

      Langkah 6 – Menyetel Pengaturan Swap Anda

      Ada beberapa opsi yang dapat Anda atur agar berdampak pada kinerja sistem Anda saat berurusan dengan swap.

      Menyesuaikan Properti Swappiness

      Parameter swappiness mengonfigurasi seberapa sering sistem Anda melakukan swap data dari RAM ke ruang swap. Ini adalah nilai antara 0 dan 100 yang mewakili persentase.

      Dengan nilai yang dekat dengan nol, kernel tidak akan melakukan swap data ke diska kecuali benar-benar diperlukan. Ingat, interaksi dengan berkas swap adalah hal “mahal” yang dalam hal ini berarti memakan waktu lebih lama daripada interaksi dengan RAM dan dapat menyebabkan pengurangan kinerja yang signifikan. Memberi tahu sistem untuk tidak terlalu banyak mengandalkan swap secara umum akan membuat sistem Anda lebih cepat.

      Nilai yang lebih dekat dengan 100 akan mencoba menaruh lebih banyak data ke dalam swap sebagai upaya untuk menjaga lebih banyak ruang RAM yang lowong. Tergantung profil memori aplikasi atau kegunaan server, ini mungkin pilihan yang lebih baik dalam beberapa kasus.

      Kita dapat melihat nilai swappiness saat ini dengan mengetik:

      • cat /proc/sys/vm/swappiness

      Output

      60

      Untuk Desktop, pengaturan swappiness 60 bukanlah nilai yang buruk. Untuk server, Anda mungkin ingin memindahkannya lebih dekat dengan 0.

      Kita dapat mengatur swappiness ke nilai yang berbeda dengan menggunakan perintah sysctl.

      Misalnya, untuk mengatur swappiness menjadi 10, kita dapat mengetik:

      • sudo sysctl vm.swappiness=10

      Output

      vm.swappiness = 10

      Pengaturan ini akan terus ada hingga boot ulang selanjutnya. Kita dapat mengatur nilai ini secara otomatis saat memulai ulang dengan menambahkan baris ke berkas /etc/sysctl.conf:

      • sudo nano /etc/sysctl.conf

      Di bagian bawah, Anda dapat menambahkan:

      /etc/sysctl.conf

      vm.swappiness=10
      

      Simpan dan tutup berkas saat Anda sudah selesai.

      Menyesuaikan Pengaturan Cache Pressure

      Nilai terkait lainnya yang mungkin Anda ingin modifikasi adalah vfs_cache_pressure. Pengaturan ini mengonfigurasi seberapa banyak sistem akan memilih untuk melakukan cache pada inode dan informasi dentry dibandingkan data lainnya.

      Pada dasarnya, ini adalah data akses tentang sistem berkas. Secara umum, ini sangat sulit untuk dicari dan sangat sering diminta, jadi sebaiknya sistem Anda melakukan cache. Anda dapat melihat nilai saat ini dengan melakukan kueri sistem berkas proc lagi:

      • cat /proc/sys/vm/vfs_cache_pressure

      Output

      100

      Dalam konfigurasi saat ini, sistem kita menghapus informasi inode dari cache dengan terlalu cepat. Kita dapat mengatur ini ke pengaturan yang lebih konservatif seperti 50 dengan mengetik:

      • sudo sysctl vm.vfs_cache_pressure=50

      Output

      vm.vfs_cache_pressure = 50

      Sekali lagi, ini hanya valid untuk sesi kita saat ini. Kita dapat mengubah hal itu dengan menambahkannya ke berkas konfigurasi seperti yang kita lakukan dengan pengaturan swappiness:

      • sudo nano /etc/sysctl.conf

      Di bagian bawah, tambahkan baris yang menentukan nilai baru Anda:

      /etc/sysctl.conf

      vm.vfs_cache_pressure=50
      

      Simpan dan tutup berkas saat Anda sudah selesai.

      Kesimpulan

      Mengikuti langkah-langkah dalam panduan ini akan memberi Anda sebagian ruang bernapas dalam kasus terkait eksepsi kehabisan memori. Ruang swap dapat menjadi sangat berguna untuk menghindari sebagian masalah umum ini.

      Jika Anda menjumpai pesan kesalahan OOM (kehabisan memori), atau jika Anda menemukan bahwa sistem tidak dapat menggunakan aplikasi yang Anda perlukan, solusi terbaiknya adalah dengan mengoptimalkan konfigurasi aplikasi atau meningkatkan server.



      Source link