Giter Club home page Giter Club logo

usersystem's Introduction

Cross platform user login system based on gRPC

A user register/login system based on gRPC C++, the client also implement in C++ and Android/iOS can share a same code base.

Just a simple demo application, including the following features

  • User register
  • User login
  • User logout
  • Client can received logout event if the same user login from a different new device, disable duplicated login
  • Sensitive data is protected by sslserver/sslchannel only if client connect to server by hostname, fallback to insecureserver/insecurechannel if client connect to server by IP address which means the system is vulnerable
  • Use mysql and mysqlx protocol api for data persistence
  • Currently, user password is stored via simple hash(sha256) algorithm, replace it with more security bcrypt password encoder

The following picture illustrate the design of this system from a developer perspective. System structure

Quick Deployment Guide

For server deployment, just run

$ git clone https://github.com/WanghongLin/UserSystem
$ cd UserSystem
$ docker-compose up

The command above will setup two image, one for our usersystem app, and another is mysql db. Docker image for gRPC is a modification version of official gRPC Dockerfile with cmake and bazel support.

After docker containers up, you can connect mysql db server from host mysql client with the following command

$ mysql -h localhost --protocol=TCP -P 33306 -uroot -pexample

Add the following volumes map to save mysql database to host after docker-compose down

volumes:
    - /my/own/datadir/in/host:/var/lib/mysql
Deploy on low end machine

If your deploy machine have a small memory footprint with limited cpu cores, it usually happen on cloud service virtual machine, you will see this error

[ERROR] [MY-012681] [InnoDB] mmap(137363456 bytes) failed; errno 12
[ERROR] [MY-012956] [InnoDB] Cannot allocate memory for the buffer pool

Consider add command option --innodb-buffer-pool-size=16M to docker-compose.yml to use a small memory pool. Use the command mysqld --verbose --help to look up more options if you need more customizations on docker mysqld.

Also, consider use a prebuilt docker image from your desktop environment by docker image save and scp into your cloud service virtual machine, then use the prebuilt image by docker image load to reduce image build time.

Finally, provide a custom http timeout to run docker

$ sudo COMPOSE_HTTP_TIMEOUT=200 docker-compose up -d

Setup development environment and build

The testing and recommended gRPC version is v1.23.x and protoc version 3.8.0

Prepare for macOS
$ brew install openssl cmake
Prepare for Linux

In order to keep the same environment with docker, follow the guide to build and install gPRC C++ for Linux, then install the requisite libssl-dev and cmake

$ apt install libssl-dev cmake
Build this project
$ git clone https://github.com/WanghongLin/UserSystem
$ cd UserSystem
$ ./build.sh

During the development cycle, use gen.sh to generate new files if you make changes to your proto, and use bazel build //:server to build with bazel.

Server setup

After build successfully, use the following command to run

$ DYLD_LIBRARY_PATH=mysqlcppconn_prebuilt/lib64:grpc_prebuilt/lib bazel-bin/server

Replace bazel-bin with cmake-build if you build with cmake and change DYLD_LIBRARY_PATH to LD_LIBRARY_PATH in Linux.

The server app support --enable-ssl and --db-url options to secure the connection with ssl if client connect from hostname and let your specify database connection respectively.

How to prevent multiple login

The following steps and picture illustrate how to disable multiple login for same user from different devices.

  1. user login in Device1 with user/pass/device_id_1
  2. new login record on server user/device_id_1
  3. user check login status in Device1 and waiting
  4. user login in Device2 with user/pass/device_id_2
  5. new login record on server user/device_id_2
  6. login record does not match for Device1, notify user in Device1 to logout

Disable multiple login

Android setup

In order to make SerializeToByte in C++ and parseFrom(byte array) in Java works, the protobuf format type should keep the same, both should use protobuf or protobuf-lite. For android, add protoc command option --java_out=lite:${OUTPUT_DIR} and optimize_for = LITE_RUNTIME declaration option to make both C++ and Java use the lite version.

Cross compile grpc++ for android arm64-v8a from cmake, and use the following command to copy all static archives to android studio project.

$ find . -name "*.a" -exec cp {} /path/to/android/project/usersystem/libs/arm64-v8a/ \;

The order of prebuilt static libraries when adding to android project matters, libgpr/libssl/libcrypto should place after libgrpc++ and libgrpc, otherwise the linker will report strange symbols undefined error.

Build android project, and use the following command to generate necessary JNI binding

$ javah -o usersystem/src/main/cpp/usersystem_client.h \
    -classpath usersystem/build/tmp/kotlin-classes/debug \
    com.wanghong.grpc.usersystem.UserSystemNative

TODO

  • add armeabi-v7a to support old non-64bits device
  • use bcrypt password hashing algorithm to hash user password instead use the simple SHA256
  • bazel build support for Android
  • iOS and Desktop client

Reference

MySQL Reference
Android Reference

usersystem's People

Contributors

wanghonglin avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.