几天前我开始学习Android,到目前为止,我完成了实现Login Activity,Main Activity,它扩展了抽象的Base活动。
单击导航栏项目从碎片打开xml。
我对成功登录后收到的令牌有疑问。成功登录后,此令牌将与每个请求一起使用以获取数据。我应该安全地将令牌保存在sqlite数据库中,还是应该在Main Activity中创建一个公共属性?主要活动将始终保留在内存中,因为这将打开片段。
答案 0 :(得分:4)
我可以建议3种选择: 1)您可以将令牌保存到文件中,如下所示:
public static void saveToken(Context ctx, String fileName, Object token) {
if (token == null) {
ctx.deleteFile(fileName);
} else {
ObjectOutputStream out = null;
try {
FileOutputStream fout = ctx.openFileOutput(fileName, 0);
out = new ObjectOutputStream(fout);
out.writeObject(token);
fout.getFD().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
确保对象token
实现java.io.Serializable interface
。
API级别24之前的用法:
saveToken(appContext, someFileName, someTokenObject);
使用API级别24及更高版本:
saveToken(appContext.createDeviceProtectedStorageContext(), someFileName, someTokenObject);
2)将SQLCipher库用于加密数据库。
3)您可以使用密钥库系统https://developer.android.com/training/articles/keystore.html
加密您的令牌答案 1 :(得分:1)
使用SharedPreferences并确保您使用Context.MODE_PRIVATE
这种方式只有您的应用才能访问数据。 SharedPreferences
是持久性商店
e.g。
SharedPreferences prefs = context.getPreferences(Context.MODE_PRIVATE);
prefs.edit().putString("token", token).apply();
token = prefs.getString("token");
为什么不使用SQLite:
SQLite是一个数据库,以表格数据为目标,单个令牌不适合这种用例。
为什么不存储在主要活动中:
主要活动在应用程序安装的生命周期内不会出现,可以随时由操作系统清理。它不是持久性数据存储。
答案 2 :(得分:0)
我应该安全地将令牌保存在sqlite数据库中,还是应该在Main Activity中创建一个公共属性?主要活动将始终保留在内存中,因为这将打开片段。
Official Android documentation已经在“安全和隐私的最佳做法”一节中回答了您的问题。它给出了以下声明:
如果您可以访问用户数据并且可以避免存储或传输它,请不要存储或传输数据
换句话说,如果你可以避免持久化,那么不会坚持。
你在问题中提到了“公共财产”,这让我想知道能见度修饰语的概念是否还不清楚。 Java public
和private
修饰符适用于controlling access to the members of your class。根据{{3}},它们与安全性无关。
如果您将令牌保留在内存中,作为public
字段或其他字段,您可能会通过将令牌存储在char[]
而不是String
。这也在this answer here详细说明。
最后,如果您必须存储令牌,则sqlite
数据库不是正确的位置。相反,您应该使用提供的this canonical answer,这将在设备受到损害的情况下更难以提取令牌。上面文档的链接包含代码示例。如果这被证明太难使用,那么它周围会有一些包装,包括KeyStore。
答案 3 :(得分:0)
1)将令牌值存储在基本应用程序单例中(您的应用程序必须是BaseApplication的实例)
public class BaseApplication extends Application {
// token
private String token = null;
public String getToken() {return this.token;}
public void setToken(String token) {this.token = token;}
}
通过上面的实现,您将能够从任何活动/片段设置并获取标记值。但是,该值不是持久的,一旦应用程序结束,它将丢失。
备注:如果您使用令牌进行REST api访问,则可以使用与上述类似的解决方案将令牌存储在后台服务实例中。
2)使用SharedPreferences - 如果您想在应用程序的运行之间存储令牌的值,这是推荐的方法。
请参阅@Ryan的回答。
答案 4 :(得分:0)
您可以使用SharedPreferences存储token.it可通过应用程序使用。
答案 5 :(得分:-1)
最好使用Sqlite
或Realm
。并存储在应用程序内存中而不是外部存储器中。至于驻留在应用程序内存中的数据,我们不必担心安全问题。保存在MainActivity中不是一个好的解决方案,因为一旦应用程序关闭,这将被清除。
存储在Shared Preference
也是一种选择。但是如果用户从设置中清除缓存,则该值也将被清除。 Realm Android Reference Link
答案 6 :(得分:-1)
您可以将其存储在共享首选项中,因为这是令牌。
现在进入安全部分您显然可以对共享首选项使用加密。
例如,您可以在图书馆下方使用很多未清项目 https://github.com/ophio/secure-preferences 关于要加密的java文件中的密钥,您需要确保在将proguard上传到playstore之前应用它。
现在,通过共享首选项,您的令牌完全安全。
为了将其保存在sqlite中而不是通过解码或root访问,您的db文件也可以作为首选项访问。关于设置中的清晰数据,我认为它也会删除你的sqlite数据。虽然不确定。
我希望它会帮助你。