Updating my hexo and icarus install
Updating Hexo Install
1 | npm install -g hexo-cli |
Updating hexo theme
- Remove node_modules folder
- remove
"hexo-theme-icarus": "^5.1.0"
inpackage.json
1 | npm install |
Updating my hexo and icarus install
1 | npm install -g hexo-cli |
"hexo-theme-icarus": "^5.1.0"
in package.json
1 | npm install |
We should always remind ourself is that, we should not store passwords yourself. At least, we should try out best to avoid it.
Password manager and 2FA is strongly suggested. However, it is not the thing I want to discuss today.
As a developer, we are unavoidably need to store user’s password.
The most naive way is to store user’s password in plain text. Once the database is leaked or have insider, all user’s password is leaked. Sadly, many people in the world are using the same username and password in different website. And thats why we should use password manager as a user.
It is a little bit better than store it as plain text. However, it still incredibly easy to get things wrong. Imagine that the database is leaked therefore Hacker have the whole database offline. They can see the encrypted code aka the ciphertext. Under lots of encryption algorithm, same text will generate same ciphertext. If it is a very large database, it most likely have many same password (especially for some easy, common passwords). The scariest part is that, some times the reset password system may also store “hints” of the password. Imagine there are 20 same encrypted password, that means I will have 20 different hints point to a same password.
hash(m)
Hashing and store the hashed password almost get the things right. However, it still can go wrong with some old hashing algorithm. let me introduce a idea, rainbow table: pre-computed hash chains. Improve on the dictionary attack to trade time for space. It is a common and strong approach to crack hash nowadays. By matching the hashed cipher text and rainbow table, hacker can easily find some of the correct match of password. If the database is compromised. Although it is the intruder who gets the hash value, it is also easy to restore the password plaintext in bulk due to the existence of rainbow tables.
The rainbow table is generated for a specific function H. If H changes, the existing rainbow table data is completely unusable. If using salt value, then a different rainbow table must be generated for each user. It greatly increases the difficulty of cracking. And the best practice is to use a different salt for each user since it is worth mentioning that, the tensor computing provided by display card to highly speed up the hack cask. Which make it even more danger now and in the future.
A practices that I have implement is make use of the fact that username is usually cannot change. Use username for as the salt.
It is common that we need to upgrade the hashing algorithm form the past but at the same time do not want to affect the user. For plain text, it just need to hash the password. And so is the encryption, it is just need to decrypt the password before hashing.
What if we already have hashed password? The fact that we cannot restore the password because hashing is a many-to-one compression. The solution is salt and pepper.
h2(h1(m)+pepper)
, salt is optional in this case. the h1 might have salted already.
hash(m+salt)
it must be safe to ensure that each user’s salt is different.
1 | version: '3' |
docker exec -it <container id> bash
The container id can be find by docker ps
mysql -u root -p
CREATE DATABASE 'newdatabase';
1 | CREATE USER 'dev'@'localhost' IDENTIFIED BY 'mypw'; |
flush privileges;
CREATE USER 'newuser'@'%' IDENTIFIED BY 'newpassword';
GRANT ALL PRIVILEGES ON newdatabase.* TO 'newuser'@'localhost';
quit
mysql -u <newuser> -p
How to build a hello world docker image by docker file
1 | console.log("Hello World") |
1 | FROM ubuntu |
FROM ubuntu
means we ubuntu the ubuntu image as the base
RUN apt update && apt install nodejs -y
means install nodejs into the ubuntu image
WORKDIR
is used to define the working directory of a Docker container.
COPY . .
is to copy the current directory(the hello-world.js) to the WORKDIR
CMD ["node", "/app/hello-would.js"]
is the command to run after the image load.
docker build -t {image name and version} .
-t
is the tag for the image name and version, for example, etklam/hello_app:0.1
.
is the Dockerfile
directory
MYSQL | what's the different betweenUTF8 and UTF8-mb4
The main different between utf8 and utf8-mb4 is utf8 is only 3 bytes but utf8-mb4 is 4bytes instead. Note that UTF8 have 4 bytes, utf8mb4 is the true utf8 character set.
In general, it is enough to use MySQL utf8 to set up a website, however, Some special (Chinese) characters or common emoji are not included in 3 bytes. Therefore, most Chinese characters are sufficient, but they cannot be used for all characters. If you want to use special characters or emoticons, you cannot use MySQL’s utf8 character set to store them.
UTF8 to UTF8mb4 does not cause incompatibility problems.
XMLHttpRequest is basic of Ajax request,
1 | const xhr = new XMLHttpRequest(); |
1 | xmlhttp.open("GET", "url"); // url is the api endpoint |
There are 5 state of xmlhttprequest, from 0 to 4
Hence, When readyState is equal to 4 and the status is 200, the response is ready.
1 | xml.onreadystatechange=function() { |
1 | function loadXMLDoc(){ |
1 |
|
in the resource/application.properties
, we can config the hibernate connection for mysql
1 | spring.jpa.hibernate.ddl-auto=create-drop |
To build a simple api, we need to add two annotaion to the main
1 |
|
Manage multiple jdks in macos, M1
First, install jenv
by using Homebrew
1 | brew install jenv |
After that, need to config the zsh
1 | echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.zshrc |
It only found the system default Java:
1 | jenv versions |
Add the jdk you installed to the jenv. Personally my jdks are installed at /Users/klam/Library/Java/JavaVirtualMachines/
For example:
jenv add /Users/klam/Library/Java/JavaVirtualMachines/azul-17.0.3/Contents/Home/
jenv global 17
to swap between different jdk for the default jdk
you can also use jenv local 17
to specifies the Java version of a folder
In Java, there are two main types of problems that can occur during the execution of a program: Errors and Exceptions.
Errors are serious issues that occur beyond the control of the application. These are typically problems related to the Java Virtual Machine (JVM) itself, such as:
StackOverflowError
OutOfMemoryError
VirtualMachineError
These errors are often unrecoverable and should not be handled in the code. When an error occurs, it’s best to let the system crash or shut down gracefully, as the environment may no longer be stable.
Exceptions are issues that arise during the normal operation of a program and can usually be anticipated and handled. For example:
Java provides a robust mechanism to handle exceptions using try-catch-finally blocks. Exceptions are further categorized into two types:
These are exceptions that are checked at compile time. The compiler requires the developer to handle these exceptions explicitly, either by using a try-catch block or by declaring them in the method signature using the throws
keyword.
Examples:
IOException
SQLException
These are exceptions that are not checked at compile time. They usually indicate programming bugs, such as logic errors or improper use of an API. These exceptions inherit from RuntimeException
.
Examples:
NullPointerException
ArrayIndexOutOfBoundsException
IllegalArgumentException
Type | Checked at Compile Time | Typically Caused By | Should Be Handled? |
---|---|---|---|
Error | No | JVM/Internal system issues | No |
Checked Exception | Yes | External issues (I/O, DB) | Yes |
Unchecked Exception | No | Programming bugs | Yes (when possible) |
Understanding the difference between errors and exceptions—and between checked and unchecked exceptions—helps in writing more robust and fault-tolerant Java applications.
Let me know if you’d like a more casual tone or if you want to turn this into a tutorial-style post!
I am working with a login api, and therefore I have some notes about Session and Token (JWT - Json web token).
The general practice of a login system should be to verify that the customer’s login information is correct. Then add a logged in attribute to the client’s session if it is correct. There are usually some tools that help us doing that. Generally the default name of the session(cookie) is “JSESSIONID”; Stored in the client’s cookie, so we don’t have to write any more complicated operations in the program.
Each time the Client Side send a request, we bring the session id along with it. Server side will take the session ID and find out the specific session from the many sessions stored in Server.
There it is, if there are 10000 user online, server need to store 10000 different session in the database. Which is a very high IO, also, there is also the problem of how to share sessions between multiple hosts.
To solve this problem, we normally use Redis.
It is very popular to use JWT as a Token instead of session. jwt is a string encrypted by the server and issued to the client.
After receiving the token, the client sends a request with the token in case of need, so that the Server can decrypt and verify the identity.
Because the token itself stores the authentication information of the client. In general, the Server will no longer store the token after it is issued.
Note that, the token can actually be stored in a cookie.
There are three part of a JWT, header, payload, signature
The whole thing will use base64 encode
sign(hash(header+payload))
The signature also certifies that only the party holding the private key is the one that signed it.
1 | // JWT code here |
Authorization: Bearer <token>
1 | public class AuthorizationCheckFilter extends OncePerRequestFilter{ |
The jwt implementation of nestjs
https://github.com/etklam/nestjs-jwt-implementation