Bảo mật luôn là vấn đề tuyệt đối quan trọng của phần mềm. Đối với ứng dụng cho thiết bị di động, thông thường chúng ta sẽ phải bảo mật các thông tin như tên tài khoản, mật khẩu, touch id, thông tin thẻ tín dụng v.v .
Thư viện react-native-keychain
cung cấp keychain/keystore để chúng ta lưu trữ và lấy thông tin lưu trữ một cách an toàn cho ứng dụng.
Cài đặt
- Chạy lệnh:
1 2 | yarn add react-native-keychain |
- Nếu version React Native <= 0.59, chạy tiếp lệnh sau để liên kết thư viện:
1 2 | react-native link react-native-keychain |
- Chạy
pod install
ở thư mục ios/ để cài đặt iOS dependencies - Nếu muốn hỗ trợ FaceID, hãy thêm NSFaceIDUsageDescription entry vào Info.plist
Sử dụng
Hãy xem ví dụ dưới đây, chúng ta sẽ lưu trữ và truy cập thông tin đăng nhập với Keychain nhé.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> Keychain <span class="token keyword">from</span> <span class="token string">'react-native-keychain'</span><span class="token punctuation">;</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> username <span class="token operator">=</span> <span class="token string">'markzuckerberg'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> password <span class="token operator">=</span> <span class="token string">'<a href="/cdn-cgi/l/email-protection" class="__cf_email__">[email protected]</a>'</span><span class="token punctuation">;</span> <span class="token comment">// Store the credentials</span> <span class="token keyword">await</span> Keychain<span class="token punctuation">.</span><span class="token function">setGenericPassword</span><span class="token punctuation">(</span>username<span class="token punctuation">,</span> password<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">// Retrieve the credentials</span> <span class="token keyword">const</span> credentials <span class="token operator">=</span> <span class="token keyword">await</span> Keychain<span class="token punctuation">.</span><span class="token function">getGenericPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>credentials<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token string">'Credentials successfully loaded for user '</span> <span class="token operator">+</span> credentials<span class="token punctuation">.</span>username <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'No credentials stored'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Keychain couldn't be accessed!"</span><span class="token punctuation">,</span> error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">await</span> Keychain<span class="token punctuation">.</span><span class="token function">resetGenericPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
setGenericPassword
Function này sẽ lưu trữ thông tin username/password vào secure storage. Lưu ý rằng function này sẽ chỉ lưu trữ string nên nếu muốn lưu trữ thông tin dạng object thì chúng ta phải chuyển sang JSON string để lưu trữ nhé.
getGenericPassword
Function này sẽ giúp chúng ta lấy được thông tin đăng nhập đã lưu ở secure storage.
resetGenericPassword
Function này sẽ xóa toàn bộ các thông tin đăng nhập đã lưu và reset nó lại.
getSupportedBiometryType
Function này sẽ dùng để check sinh trắc học mà thiết bị hỗ trợ
1 2 3 4 | Keychain<span class="token punctuation">.</span><span class="token function">getSupportedBiometryType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">biometryType</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> biometryType <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Sử dụng với server
Thư viện này cũng cung cấp API để lưu trữ server information cùng với username và password.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> Keychain <span class="token keyword">from</span> <span class="token string">'react-native-keychain'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> DeviceInfo <span class="token keyword">from</span> <span class="token string">'react-native-device-info'</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> username <span class="token operator">=</span> <span class="token string">'markzuckerberg'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> password <span class="token operator">=</span> <span class="token string">'<a href="/cdn-cgi/l/email-protection" class="__cf_email__">[email protected]</a>'</span><span class="token punctuation">;</span> <span class="token keyword">const</span> server <span class="token operator">=</span> DeviceInfo<span class="token punctuation">.</span><span class="token function">getBundleId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// Store the credentials</span> <span class="token keyword">await</span> Keychain<span class="token punctuation">.</span><span class="token function">setInternetCredentials</span><span class="token punctuation">(</span>server<span class="token punctuation">,</span> username<span class="token punctuation">,</span> password<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">// Retreive the credentials</span> <span class="token keyword">const</span> credentials <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getInternetCredentials</span><span class="token punctuation">(</span>server<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>credentials<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Credentials successfully loaded for user '</span> <span class="token operator">+</span> credentials<span class="token punctuation">.</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'No credentials stored'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Keychain couldn't be accessed!'</span><span class="token punctuation">,</span> error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">await</span> Keychain<span class="token punctuation">.</span><span class="token function">resetInternetCredentials</span><span class="token punctuation">(</span>server<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Chú thích
Đối với Android, module này sẽ implement CipherStorage dựa trên API level:
- API level 16-22 sẽ en/de crypt sử dụng Facebook Conceal
- API level 23+ sẽ en/de crypt sử dụng Android Keystore
Thông tin đã mã hóa sẽ được lưu trữ ở SharedPreference.
Tham khảo:
- Tham khảo ví dụ chi tiết tại: https://github.com/oblador/react-native-keychain