Frontend:
import React, {useState} from 'react'
import { useHistory } from "react-router-dom";
import {useForm} from "react-hook-form";
import './RegisterForm.css'
function RegisterForm() {
let history = useHistory();
const {register, handleSubmit, getValues, formState: { errors } } = useForm();
const [userRole, setUserRole] = useState('')
const onSubmit = (data, e) => {
e.preventDefault()
data['role'] = userRole
fetch('/api/user/register', {
method: 'POST',
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify(data)
})
.then(res => console.log(res.json()))
history.push('/user/login')
}
return (
<div className="columns">
<div className="column is-narrow-desktop is-offset-5">
<div className="card is-3 mt-5">
<header className="card-header">
<p className="card-header-title has-text-primary-light has-background-dark">
User Registration
</p>
</header>
<div className="card-content">
<div className="content">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="field">
<div className="control">
<select name="role" required
value={userRole}
onChange={(e) => setUserRole(e.target.value)}>
<option value="" disabled defaultValue="" hidden>Role</option>
<option value="Contractor" >Contractor</option>
<option value="Customer">Customer</option>
</select>
</div>
</div>
<div className="field control">
<input placeholder="Username" name="username"
{...register("username", {required: true, minLength: 3})} />
<p className="help is-danger">
{errors.username?.type === 'required' && "This field is required"}
{errors.username?.type === 'minLength' && "This field must contain at least 3 characters"}
</p>
</div>
<div className="field control">
<input placeholder="Email" id="email"
autoComplete="email"
{...register("email", {required: true, pattern: /\S+@\S+\.\S+/})} />
<p className="help is-danger">
{errors.email?.type === 'required' && "This field is required"}
{errors.email?.type === 'pattern' && "Invalid email address"}
</p>
</div>
<div className="field control">
<input type="password" placeholder="Password" id="password" name="password"
autoComplete="new-password"
{...register("password", {required: true, minLength: 6})} />
<p className="help is-danger">
{errors.password?.type === 'required' && "This field is required"}
{errors.password?.type === 'minLength' && "This field must contain at least 6 characters"}
</p>
</div>
<div className="field control">
<input type="password" placeholder="Retype Password" id="confirm_password"
autoComplete="new-password"
{...register("confirm_password", {required: true, minLength: 6,
validate: value => value === getValues('password')})} />
<p className="help is-danger">
{errors.confirm_password?.type === 'required' && "This field is required"}
{errors.confirm_password?.type === 'minLength' && "This field must contain at least 6 characters"}
{errors.confirm_password?.type === 'validate' && "Passwords don't match"}
</p>
</div>
<div className="control">
<input type="submit" value="Register" className="button is-link" />
</div>
</form>
</div>
</div>
</div>
</div>
</div>
)
}
export default RegisterForm
Backend – główny plik: __init__py
def create_app(Config):
app = Flask(__name__, static_folder='../build', static_url_path='/')
app.config.from_object(Config)
api.init_app(app)
db.init_app(app)
app.db = db
bcrypt = Bcrypt(app)
app.bcrypt = bcrypt
from .common import utils
from .common import routes
app.register_blueprint(api_bp)
app.register_blueprint(utils.bp)
app.register_blueprint(routes.bp)
return app
from api.resources.auth import UserRegister
api.add_resource(UserRegister, '/api/user/register', endpoint='user_register')
Plik zawierający klasę Resource dla obsługi rejestracji użytkownika:
from flask import current_app, request
from flask_restful import Resource
from api.common.parsers import parser
from ..common.utils import send_email
from ..common.models import User
from .. import db
class UserRegister(Resource):
def post(self):
req = request.json
username = req['username']
password = req['password']
email = req['email']
role = req['role']
bcrypt = current_app.bcrypt
hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')
status = send_email(email, category='confirm_account')
user = User(username=username, password=hashed_password, email=email, role=role)
db.session.add(user)
db.session.commit()
return {"message": status}