Create a function to register & log in the information entered from the Unity side. As before, we will set up and use an application server locally in Flask.
[Last time]: [Unity (C #), Python] API communication study memo ② Launch local server with Flask
Masakari is all okay because there are a lot of interpretations that I don't understand. ** Especially when it comes to security, it's embarrassing to call myself an engineer ** Even if you cut it with a huge Masakari, it will be accepted firmly.
You can register an account by entering your ID and password. You can actually log in on the login screen.
It is an image of what you are doing.
Since the information is saved in the DB, the account information will not be deleted even if you close the Editor. (maybe)
The process performed by Unity is to send the entered information to the local server and Just display the text in response.
Processing related to registration button
using System.Collections;
using UnityEngine.Networking;
using UnityEngine;
using System.Text;
using UnityEngine.UI;
public class RegistraionHTTPPost : MonoBehaviour {
[SerializeField, Header("LogText")]
Text m_logText;
[SerializeField, Header("IDInputField")]
InputField m_idInputField;
[SerializeField, Header("PassInputField")]
InputField m_passInputField;
//URL to connect to
private const string RegistrationURL = "http://localhost:5000/registration";
//Game object UI>Button Inspector> On Click()Method to call from
public void Registration()
{
StartCoroutine(RegistrationCoroutine(RegistrationURL));
}
IEnumerator RegistrationCoroutine(string url)
{
//Information to POST
WWWForm form = new WWWForm();
form.AddField("user_id", m_idInputField.text, Encoding.UTF8);
form.AddField("password", m_passInputField.text, Encoding.UTF8);
//Prepare URL by POST
UnityWebRequest webRequest = UnityWebRequest.Post(url, form);
//Set buffer in UnityWebRequest
webRequest.downloadHandler = new DownloadHandlerBuffer();
//Connect to the URL and wait for the results to come back
yield return webRequest.SendWebRequest();
//Check for errors
if (webRequest.isNetworkError)
{
//Communication failure
Debug.Log(webRequest.error);
m_logText.text = "Communication error";
}
else
{
//Successful communication
Debug.Log("Post"+" : "+webRequest.downloadHandler.text);
m_logText.text = webRequest.downloadHandler.text;
}
}
}
The following parts are responsible for sending information to the local server.
As information received by the local server side
ʻUser_id,
password, etc. are added to
form` as request information.
Information to send at the time of request
//Information to POST
WWWForm form = new WWWForm();
form.AddField("user_id", m_idInputField.text, Encoding.UTF8);
form.AddField("password", m_passInputField.text, Encoding.UTF8);
I don't understand in detail, but
form
seems to be able to pass some information in addition to the request type (POST, GET, etc.).
WWWForm
is a POST-only class.
This is really difficult, ** What should I do in the first place ** It was a long and difficult situation.
First of all, I found out that it is necessary to use a DB (database) to register account information **.
A database (English: database, DB) is a collection of information organized for easy retrieval and storage. Usually, it refers to what is realized by a computer, but a paper address book may be called a database. In a database system using a computer, a database management system, which is software for managing the database, is often used.
[Source]: [Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3 % 83% BC% E3% 82% B9)
The database seems to be software. If you dig deeper to fully understand where the data is and how it works, I don't think deeply because a great person said that I wouldn't be able to come back. [Reference link]: What is a database made of in the first place, and where and how is it stored? ..
There are various types of DB, and this time I use it like ** RDB (relational database) **.
SQLAlchemy
A library called SQL is used to actually operate the database, but it is done from within Python.
[Source]: First Flask # 4 ~ Let's play with the database with SQLAlchemy ~
That's right. It's convenient! This time I will use this.
It's finally Flask and DB implementation.
import hashlib
from flask import *
from sqlalchemy import create_engine, Column, String, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
app = Flask(__name__)
engine = create_engine('sqlite:///user.db')
Base = declarative_base()
#DB settings
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, unique=True)
user_id = Column(String)
password = Column(String)
Base.metadata.create_all(engine)
SessionMaker = sessionmaker(bind=engine)
session = scoped_session(SessionMaker)
#Register ID and password in DB
@app.route("/registration", methods=["POST"])
def registration():
user = request.form["user_id"].strip()
check_users = session.query(User).filter(User.user_id == user).all()
if check_users:
return "That username has been used"
else:
user = User(user_id=request.form["user_id"], password=str(hashlib.sha256(
request.form["password"].strip().encode("utf-8")).digest()))
session.add(user)
session.commit()
return str(user.user_id.strip() + "Mr\n Thank you for registering")
#Check the DB to see if it is a combination of ID and password that can be logged in
@app.route("/login", methods=["POST"])
def login_check():
user = request.form["user_id"].strip()
check_users = session.query(User).filter(User.user_id == user).all()
try:
for login_user in check_users:
login_user_pass = login_user.password
if login_user_pass == str(hashlib.sha256(
request.form["password"].strip().encode("utf-8")).digest()):
return "Login is complete"
else:
return "Password is different"
except:
return "Registration information is different"
if __name__ == "__main__":
app.run(debug=True)
# User.__table__.drop(engine) #For table deletion
If you uncomment the following part and move it, it will disappear.
User.__table__.drop(engine) #For table deletion
I'm writing pyhton in VSC, but Flask didn't get along with Pylint.
Therefore, I opened Setting.json and added the following settings.
"python.linting.pylintArgs": [
"--load-plugins",
"pylint_flask"
],
This time, I wanted to do ** hashing and security measures are perfect! ** At present, only part (2) has been created, so I feel that it is completely meaningless. There are a lot of articles saying that security is not enough just by using POST. I'm wondering if all the information to be exchanged must be hashed. If you know more about this area, please let me know.
I found out when I was investigating security. It seems that there are different types of authentication.
Digest authentication is superior to Basic authentication in terms of security. However, it is not compatible with all environments. If you know the environment of the user who uses the page to some extent and you are using a compatible browser, there is no problem. However, Digest authentication is not suitable for setting on a page for an unspecified number of users.
On the other hand, Basic authentication is inferior to Digest authentication in terms of security. However, there should be no problem if you use it in an environment where security measures are taken in advance, such as SSL or in a local network. It does not depend on the user's environment.
In this way, when setting user authentication on a page used by an unspecified number of users, Basic authentication combined with SSL, Digest authentication when the connection environment such as an administrator is specified, depending on the situation Is common.
[Source]: Basic authentication (basic authentication) and Digest authentication, their roles and differences
Does the one implemented this time correspond to what is called Basic authentication? I'm not sure, so I'd like to know because it's okay to say, "You didn't make either."
[Python ORM] Summary of basic SQL queries with SQLAlchemy
Recommended Posts